2016-07-29 18 views
2

enter image description hereIst das ein innodb Gap Lock Bug?

TRX1 select * from Tabelle, wo refId = 4 for update

TRX2 in Tabelle einfügen (refId) -Werten (2); Block

trx2 wird blockiert, ich wusste, dass trx1 es Lückensperre halten wird, [1,4), [4,7);

meine Frage ist, warum Lückensperre halten? "insert val 2" ist kein Konflikt "where refId = 4 for update", warum innodb Lückensperrung beibehalten wird, warum nicht record-lock verwenden?

diese Frage stört mich schon lange, bitte tech gott rette mich.

Antwort

1

Interessante Frage.

Die Lückensperre wird benötigt, um phantom rows zu vermeiden. MySQL arbeitet standardmäßig in der REPEATABLE-READ-Isolationsebene. Wenn Sie in Ihrer Transaktion mehrmals select ... for update ausführen, sollte es immer dasselbe Ergebnis zurückgeben. Angenommen, Sie haben keine Lückensperre und trx2 hat eine weitere Zeile mit refId = 4 eingefügt (der Index ist nicht eindeutig). Dann folgende Auswahl in TRX1 werden zwei Zeilen zurück:

MariaDB [test]> select * from t1 where refId=4 for update; 
+----+------+ 
| id | refId| 
+----+------+ 
| 2 | 4 | 
| 4 | 4 | 
+----+------+ 
2 rows in set (0.00 sec) 

Es ist nicht das gleiche Ergebnis wie zuerst wählen.

+0

ja, das ist richtig, void Phantom Zeilen, wie folgt Ihrem Test, fügen Sie eine andere Zeile mit refId = 4, solange trx1 die Zeile Datensatz sperren (oder nicht Gap-Sperre), Sie können einfügen refId = 4, und leere Phantomzeilen; meine Frage, warum Gap-Lock zu Block-Einsatz halten RefId = 1,2,3,5,6, nicht nur 4. Fühlen Sie sich das ist Mysql Bug? –

+0

Ich denke, Gap-Lock-Arbeit auf dieser sql "Select * aus der Tabelle, wo refId <10 für update", Gap-Lock wird Blockierung refId = 1,2,3,4,5,6,7 zu ​​void Phantom Zeilen blockieren; Es sollte Arbeit Bereichssuche Bedingung, nicht gleich Bedingung. –

+0

danke für deine antwort. –