Wie kann ich einen Deadlock mittels SELECT erzeugen?

Themen rund um den praktischen Einsatz von Firebird. Fragen zu SQL, Performance, Datenbankstrukturen, etc.

Moderator: thorben.braun

Antworten
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Guten Morgen zusammen,

ich baue derzeit die Testszenarien für den PHP-Treiber um. Hier gibt es einen Test rund um Transaktionen.

Folgendes Szenario:

Code: Alles auswählen

$tr_1 = ibase_query("SET TRANSACTION"); // Standard READ WRITE Transaktion
$tr_4 = ibase_trans(IBASE_READ+IBASE_COMMITTED+IBASE_REC_NO_VERSION+IBASE_NOWAIT);
Anschließend wird in Transaktion 1 ein Insert ausgeführt.

Code: Alles auswählen

Transaktion 1: insert into test5 (i) values (4)
Abschließend soll ein Deadlock mittels SELECT erzeugt werden.

Code: Alles auswählen

Transaktion 4:  "select * from test5";
Die erwartete Meldung sieht in etwa so aus:

Code: Alles auswählen

lock conflict on no wait transaction deadlock
Bei mir erzeugt die Anweisung jedoch kein Deadlock, sondern liefert die Daten aus.

Starte ich die Transaktion mit dem Flag IBASE_CONSISTENCY, erhalte ich eine Konfliktmeldung.

Wurde in den Isolationsmodes etwas von 2.5 auf 3.0 geändert? Oder hat jemand eine andere Idee einen Deadlock mittels SELECT zu provozieren?

Dank und Gruß
Martin
Martin Köditz
it & synergy GmbH
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Das liegt an der Satzversion. Da gibts so keine Sperren.
Es wird aber ein

Select * from Table for update

unterstützt, der tatsächlich einen Lock auf eine Zeile setzen kann.
Das nutze ich z.B. um Metadatenänderungen wie Create Table über Sitzungsgrenzen hinweg zu serialisieren.
vr2
Beiträge: 214
Registriert: Fr 13. Apr 2018, 00:13

Das ist kein deadlock (= gegenseitige Blockade), wird leider schon lange von Firebird unkorrekt gelabelt.

Ja, es wurde bei den TX-defaults etwas verändert, schau mal unter ReadConsistency in der firebird.conf. Und natürlich das Verhalten des Metadaten-Cache beim SuperServer ab v3, aber das weißt Du wahrscheinlich.

Grüße, Volker
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Ehrlich gesagt weiß ich das nicht, da diese Sperre schon selt 2.x lange genutzt wird.
Ich habe noch mal geschaut:
Gemacht wird ein expliziter "select ... with lock".
Da ich generell nur mit ReadCommitted sowie WaitTimeout arbeite funktioniert dieser Lock.
Vom Konzept mache ich folgendes (VB6-Code):

Code: Alles auswählen

                        "begin begin in autonomous transaction Do begin " & _
                        "xCmd = '" & pSQL & "';  for " & _
                        "select first 1 a.lockvalue from zgloballock a with lock into :xvalue " & _
                        "Do  begin " & _
                        "execute statement :xcmd; " & _
                        "xCmd='alter index " & xName & " inactive';" & _
                        "execute statement :xcmd; " & _
                        "when any  do begin exception; end " & _
                        "End End End " & _
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Hast du deinen Deadlock nun hinbekommen?
Antworten