インデックス付き列の値を上下に設定することへの依存性から、ロックが実際にインデックスエントリに設定されているように見えます。データベースエンジンはインデックスをスキャンし、最初にロックされたエントリで停止し、解放されるのを待ちます。
最初のトランザクションがコミットされると、インデックスのロックが解除され、待機中のトランザクションはインデックスのスキャンを続行します。値が下がったため、インデックスの初期になりました。したがって、再開されたスキャンは、すでにそのポイントを通過しているため、それを認識しません。
これを確認するには、次のテストを試してください。
- 値2と3の2つの行を作成します。
- 両方のトランザクションで、
SELECT ... FOR UPDATE
を実行します - トランザクション1で、2を1に、3を4に変更します。
- トランザクション1をコミットします。
私の推測が正しければ、トランザクション2は4の行だけを返すはずです。
このような部分的な結果が得られるとは思わないので、これは私にはバグのように思えます。残念ながら、bugs.mysql.comでこれを検索することは困難です。これは、「for」という単語が短すぎるか一般的であるため、検索時に無視されるためです。 「更新用」を引用しても、このフレーズのみを含むバグは見つからないようです。