Seite 1 von 1

Wie kann ich einen Deadlock mittels SELECT erzeugen?

Verfasst: Fr 3. Feb 2023, 11:44
von martin.koeditz
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

Re: Wie kann ich einen Deadlock mittels SELECT erzeugen?

Verfasst: Fr 3. Feb 2023, 22:45
von bfuerchau
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.

Re: Wie kann ich einen Deadlock mittels SELECT erzeugen?

Verfasst: Di 7. Feb 2023, 00:15
von vr2
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

Re: Wie kann ich einen Deadlock mittels SELECT erzeugen?

Verfasst: Di 7. Feb 2023, 08:48
von bfuerchau
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 " & _

Re: Wie kann ich einen Deadlock mittels SELECT erzeugen?

Verfasst: Do 9. Feb 2023, 16:51
von bfuerchau
Hast du deinen Deadlock nun hinbekommen?