Aus der Abhängigkeit, den Wert einer indizierten Spalte höher oder niedriger zu setzen, sieht es so aus, als würde die Sperre tatsächlich auf den Indexeintrag gesetzt. Die Datenbank-Engine scannt den Index und stoppt beim ersten gesperrten Eintrag und wartet darauf, dass er freigegeben wird.
Wenn die erste Transaktion festgeschrieben wird, wird der Index entsperrt und die wartende Transaktion fährt mit dem Scannen des Index fort. Da der Wert gesenkt wurde, steht er nun früher im Index. Der fortgesetzte Scan sieht es also nicht, weil er diesen Punkt bereits passiert hat.
Um dies zu bestätigen, versuchen Sie den folgenden Test:
- Erstellen Sie zwei Zeilen mit den Werten 2 und 3.
- Führen Sie in beiden Transaktionen das
SELECT ... FOR UPDATE
durch - Ändern Sie in Transaktion 1 2 zu 1, 3 zu 4.
- Transaktion 1 festschreiben.
Wenn meine Vermutung richtig ist, sollte Transaktion 2 nur die Zeile mit 4 zurückgeben.
Dies scheint mir ein Fehler zu sein, da ich nicht glaube, dass Sie jemals solche Teilergebnisse erhalten sollten. Leider ist es schwierig, auf bugs.mysql.com danach zu suchen, weil das Wort „for“ bei der Suche ignoriert wird, weil es zu kurz oder zu häufig ist. Selbst das Zitieren von "for update" scheint keine Fehler zu finden, die nur diesen Ausdruck enthalten.