phpbar.de logo

Mailinglisten-Archive

InnoDB deadlock - weshalb ?

InnoDB deadlock - weshalb ?

Riki Cubek riki.cubek at web.de
Fre Jun 25 11:33:12 CEST 2004


Hallo, 
 
ich weiss zwar, wie ein klassischer Deadlock bei Transaktionen zu Stande kommt (zwei Threads warten auf die Freigabe einer Resource des jeweils anderen), dennoch verstehe ich nicht, weshalb es in folgender Situation zum Deadlock kommt (Der Code macht nicht viel Sinn, ich merkte es zufaellig als ich aus einem sinvollen Test einiges auskommentierte). 
 
Ich habe eine leere Tabelle A, Thread 1 starte ich etwa 1 Sekunde vor Thread 2 (einfach 2 Browserfenster, Zugriff ueber PHP), nun mit Pseudo-code: 
 
Thread 1: 
 
starte Transaktion; 
schlafe 3 Sekunden; 
gibt es in Tabelle A Zeile 'X' ? ('SELECT * from A where col_1 = 'X' for update', also exclusive lock); 
schlafe 3 Sekunden; 
falls NEIN, schlafe 5 Sekunden und fuege Zeile 'X' in Tabelle A ein; 
beende Transaktion; 
 
Thread 2: 
 
starte Transaktion; 
schlafe 3 Sekunden; 
fuege Zeile 'X' in Tabelle A ein; 
beende Transaktion; 
 
 
Thread 2 hat keine Probleme, er fuegt die Zeile ein, aber erst, nachdem Thread 1 seine Transaktion beendet hat (wie erwartet). Thread 1 aber meldet unmittelbar vor Schluss (also beim Versuch die Zeile 'X' einzufuegen) einen Deadlock: 
 
Deadlock found when trying to get lock; Try restarting transaction
 
Meinem Verstaendnis nach koennte es eigentlich nur daran liegen, dass Thread 2 fuer die INSERT-Anweisung einen exklusiven Lock auf den Index in Tabelle A erfragt, auf diesen aber warten muss da ihn Thread 1 bereits mi der SELECT ... FOR UPDATE Anweisung erhielt. Nun versucht Thread 1 seinerseits eine Zeile einzufuegen, und es kommt zum Deadlock - weil er auf die Freigabe durch Thread 2 warten muss ? Thread 1 hat doch den exclusive Lock laengst...?
Ich verstehen nicht, wie es bei Anwendung einer einzigen Tabelle zum Deadlock kommen kann, die Sperre kann doch immer nur ein Thread erlangen - oder gibt es hier mehrere, verschiedene Sperren ?
 
Zur vollstaendigen Verwirrung las ich dann noch, dass ein INSERT nur die eingefuegte Zeile sperrt: 
INSERT INTO ... VALUES (...) sets an exclusive lock on the inserted row. Note that this lock is not a next-key lock and does not prevent other users from inserting to the gap before the inserted row. 
 
Ich vermute, dass ich das Prinzip absolut nicht begriffen habe, kann mir nun mal einer den Ausgang meines Versuches erklaeren ?

Ferner wuerde mich interressieren, wie genau funktioniert row-level locking ?
Wie und welche Zeilen werden bei FOR UPDATE und IN SHARED MODE selects gesperrt ?

Bin am verzweifeln, das kann doch nicht so schwer sein - eine dataillierte Erklareung finde ich nun mal aber nicht...

mfg

Riki
_______________________________________________________
WEB.DE Video-Mail - Sagen Sie mehr mit bewegten Bildern
Informationen unter: http://freemail.web.de/?mc=021199

-- 
Infos zur Mailingliste, zur Teilnahme und zum An- und Abmelden unter
-->>  http://www.4t2.com/mysql 


php::bar PHP Wiki   -   Listenarchive