SQLServerのデッドロックグラフの読み方
JavaEEで開発したアプリケーションで、デッドロックが大量に発生しました。
SQLServerのsystem_healthを見てみると、あるテーブルXに対するDELETEのトランザクション同士によるデッドロックです。
system_healthからこの画像が見れるのですが、これの読み取り方を教えてください。
黒塗りで消してある部分は
Object name:「テーブルX」
Index name:「テーブルXのインデックスY」
です。
「キーロック」の枠が2つありますが、どちらも同じ内容でした。
以下の解釈は正しいですか?
1. 獲得済みロックとロック要求の解釈
- プロセスID367 が、ロック対象Bの更新ロックを獲得済み(Owner Mode: U)
- プロセスID391 が、ロック対象Aの排他ロックを獲得済み(Owner Mode: X)
という状況において、
お互いに逆のロック対象に対する更新ロックを要求(Request Mode: U)して、デッドロックを引き起こしている。
2. ロック対象の解釈
ロック対象A、Bはともに、インデックスY全体に対するロックである。
つまり、AとBは同じものであり、同一の対象でデッドロックが発生している。
正しいとした場合の疑問
同一対象への更新ロックは競合するのでは?
この解説によると、更新ロックは共有ロックとしか互換性がなく、同一対象に2つの更新ロックは持てないはずです。
従って、私の解釈の2と矛盾します。
恐らく解釈が間違っていると思うのですが・・・
どなたか、正しい解釈を教えていただけないでしょうか。
※最終的には原因究明と回避策を検討しますが、まずはこのsystem_healthの情報を正しく解釈したいという主旨の質問です。
環境の情報
- SQLServerのバージョンは2017
- トランザクション分離レベルは READ COMMITTED
- Is Read Committed Snapshot On = False
- スナップショット分離を許可 = False
追加情報
- テーブルXにトリガーはありません
Understanding the graphical representation of the SQL Server Deadlock Graph
グラフの読み方はこれを見て理解したつもりです。英語が苦手なので解釈に自信が無いのですが・・・Owner edge
Occurs when resources are waiting on processes. In this case the Person.person table is waiting on process 62 to release it.
テーブル「Person.person」はプロセス62がロックを解放するのを待っている=プロセス62がテーブル「Person.person」のロックを持っている、ですよね?
- SQL発行時にヒントは含めていません。
- ロック対象を指定していないです。