|+-----------------+そして状態を確認するために下記のコマンドを実施しておきます。これによってトランザクションの状態を出力する際にロックの詳細も一緒に出力してくれるようになります。ON;どういうロックがかかっているのかでは先の例に沿って実行していきます。下記のdelete文を発行した時点で各トランザクションがどういうロックの取得を行っているのか確認してみます。80;この時点で下記のコマンドによってトランザクションの状態を確認します。モニターテーブルを作成してそちらを参照しても良いです。status\Gするといろいろ出力されるのですが、トランザクションのロック取得状況を表す箇所を抜粋します。0確認するとテーブルに対するインテンション排他ロックidxSecondaryIdインデックスに対する排他ネクストキーロックが取得されているようです。テーブルに対するインテンションなロックはこの場合にはデッドロックを引き起こさないので無視します。続いてトランザクション2にも同じ手順に沿って実施してもらいましょう。0トランザクション1と同様のロックを取得していることが確認できます。ここで一つ注目したいのはこれら2つのステートメントの実施はロック待ち状態が発生することなく実施することができました。いうことがわかりました。ネクストキーロックとは何なのだろうこれに気づいた時結構驚きました。ネクストキーロックって、指定の値に対してレコードロックとさらにその前のインデックスとのギャップを含むと説明があるではありませんか。範囲のネクストキーロックを取得するのではないかと考えました。わかりやすいように図を用意しましょう。インデックスの並びで、ボックスが取得しようとしているロックの範囲を表しています。双方のロックが取得しているということは、この仮定が誤っているという結論になります。この解釈は後で述べることにして、とりあえず先に進みます。ここでTrx1がロックが取得できずに待ち状態になりますここでロック取得待ちが発生します。トランザクション1のロック取得状態を確認してみましょう。0一つロックが増えていますね。これは挿入インテンションギャップロックというやつです。対するネクストキーロックによりブロックされているという状況になります。transactionデッドロックが起こったことが確認できました。状況を整理して客観的に見たときに、下記のような条件が成り立っています。2つのトランザクションがはじめにdelete文により取得したネクストキーロックはお互いのロック領域に重なっていないその後発行するinsert文が取得しようとする挿入インテンションギャップロックはお互いのネクストキーロックに重なっている逆にこれが成り立つような状況を想像できればネクストキーロック、挿入インテンションギャップロックが取得しようとするロックの範囲を推測できます。自分なりに解釈した結論が下記のようになりますネクストキーロックについてネクストキーロックはインデックス値の前のギャップも取得することもあるが、ギャップを取得しないこともある。レコードロックの範囲に等しい挿入インテンションギャップロックについて挿入インテンションギャップロックが取得しようとするギャップは、挿入するレコードが該当するギャップに等しい範囲が対象となる。以降のギャップロックを取得しようとするわかりにくいと思うので図にします。これまた会心の出来です。矢印はレコードロックを表しています。こんな形になるんではなかろうかと。記事に記載されていること以外にも色々試行錯誤したのですが、すべての結果を説明できるので自分としてはこんな形であろうと解釈しました。(本当は実装レベルで把握できれば良いんだろうけれども。今回の対応としては削除時に主キーのレコードロックのみを取得して削除するような実装に変更しました。AM同じような問題にぶち当たった過去があります。DELETE&INSERT時のロックの種類も同様に調査し、そして、、結局のところ謎が更に深まり、妥協という感じで決着しました。COMMITTEDにすることで、ギャップロックを無効化(=つまり、排他ネクストキーロックも)できるような記述があり、小躍りして試してみましたが、セカンダリインデックスでDELETE実行後にINSERTを複数プロセスで実行したところ、ロックの嵐でした。頭道さんの対応方法が泣けます。私も同じような対応方法を検討しましたが、私の場合は、セカンダリインデックスで数百万件のレコード削除だったので、ID指定で1件ずつでも、あるいは自前で生成した静的IN句で数千件ずつでも埒が明かなかったので、DELETE&INSERTではなくて、ひたすらINSERTを並列動作で許容し、切りのいいタイミングで、削除バッチにて古い断面分を削除するような作りに変えて対応しました。ロックは鬼門です、本当に。ちなみに、本件の場合、先のSQLでギャップロックがかからなかったのは、おそらくですが、実質ユニークキーだったことも関係しているのではないかと。ユニークキー(例えばPK)に対する、【ユニークアクセス】なレコードロックは=インデックスレコードロックであり、ギャップを握らないのはご存知かと思いますが、存在しないレコードに対するインデックス走査時でもユニーク性がある場合は、ネクストキーロックが行われない場合がある?、、のかなと。コメントをキャンセルメールアドレスが公開されることはありません。コメントデータの処理方法の詳細はこちらをご覧ください。APIのOAuth認証に失敗するyumの設定ファイルを確認するRECOMMENDこちらの記事も人気です。