SELECT FOR UPDATE
レコードの排他ロックを取得する前に、テーブルの意図的な排他ロックを取得します。
したがって、このシナリオでは:
X1: SELECT FOR UPDATE -- holds IX, holds X on 'lock_name'
X2: SELECT FOR UPDATE -- holds IX, waits for X on 'lock_name'
X1: INSERT -- holds IX, waits for X for the gap on `id`
両方のトランザクションがIX
を保持しているため、デッドロックが発生します テーブルをロックしてX
を待つ レコードをロックします。
実際、このシナリオは MySQL
ロックに関するマニュアル
。
これを回避するには、検索しているインデックス、つまり lock_name
を除くすべてのインデックスを削除する必要があります。 。
id
に主キーをドロップするだけです 。