56469


JavaEEで開発したアプリケーションで、デッドロックが大量に発生しました。  
SQLServerのsystem_healthを見てみると、あるテーブルXに対するDELETEのトランザクション同士によるデッドロックです。

system_healthからこの画像が見れるのですが、これの読み取り方を教えてください。

[![画像の説明をここに入力](https://i.stack.imgur.com/KPVu0.png)](https://i.stack.imgur.com/KPVu0.png)

黒塗りで消してある部分は  
Object name：「テーブルX」  
Index name：「テーブルXのインデックスY」  
です。  
「キーロック」の枠が２つありますが、どちらも同じ内容でした。

## 以下の解釈は正しいですか？

### 1\. 獲得済みロックとロック要求の解釈

  * プロセスID367 が、ロック対象Bの更新ロックを獲得済み(Owner Mode: U)
  * プロセスID391 が、ロック対象Aの排他ロックを獲得済み(Owner Mode: X)

という状況において、  
お互いに逆のロック対象に対する更新ロックを要求(Request Mode: U)して、デッドロックを引き起こしている。

### 2\. ロック対象の解釈

ロック対象A、Bはともに、インデックスY全体に対するロックである。  
つまり、AとBは同じものであり、同一の対象でデッドロックが発生している。

## 正しいとした場合の疑問

### 同一対象への更新ロックは競合するのでは？

[この解説](https://docs.microsoft.com/ja-jp/sql/2014-toc/sql-server-transaction-
locking-and-row-versioning-guide?view=sql-server-2014#lock-
compatibility)によると、更新ロックは共有ロックとしか互換性がなく、同一対象に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](https://www.sqlshack.com/understanding-graphical-representation-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発行時にヒントは含めていません。 
    * ロック対象を指定していないです。


CC BY-SA 4.0
2019-06-27T06:44:33.270
56138
2019-07-07T06:27:45.027
2019-06-30T23:36:45.293
8078
8078
question
sql-server
SQLServerのデッドロックグラフの読み方


ちょっと試してみた範囲では、Request Mode: Xでデッドロックしましたが、ほぼ同じ現象を出せました

解釈の間違ってる点ですが

> ロック対象A、Bはともに、インデックスY全体に対するロックである。

インデックス全体に対するロックではなく、インデックスのキー範囲に対するロックです  
なので対象インデックスが同じでも、違うキーに対するロックは複数が同時に存在しえます

対策案は、  
同一キーに対する削除があるなら、nowait指定で削除でのロック待ちをなくすぐらいですかね  
こちらはデッドロックではなくロックタイムアウトでエラーはでるので適切なハンドリングが必要ですが


CC BY-SA 4.0
2019-07-07T06:09:45.427
56469
2019-07-07T06:27:45.027
2019-07-07T06:27:45.027
9811
9811
56138
answer