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に主キーをドロップするだけです 。