適用対象:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
Microsoft Fabric プレビューの SQL データベース
この記事では、データベース エンジンのデッドロックの詳細について説明します。 デッドロック状態は、多くの場合はマルチステップ トランザクションにおいてデータベース内で競合する同時実行のロックにより発生します。 トランザクションとロックの詳細については、「 トランザクション ロックと行のバージョン管理ガイド」を参照してください。
Azure SQL Database と Fabric の SQL データベースでのデッドロックの識別と防止の詳細については、「Azure SQL Database と Fabric の SQL データベースでのデッドロックの分析と防止」を参照してください。
デッドロックについて
デッドロックは、複数のタスクが永続的に相互ブロックすることで発生します。つまり、一方のタスクがロックを試みているリソースに他方のタスクがロックを獲得していて、これが相互に行われるとデッドロックが発生します。 例えば次が挙げられます。
トランザクション A では、行 1 の共有ロックが取得されます。
トランザクション B では、行 2 の共有ロックが取得されます。
このとき、トランザクション A で行 2 の排他ロックが要求されますが、トランザクション B が終了し、保持されている行 2 の共有ロックが解放されるまで A はブロックされます。
このとき、トランザクション B で行 1 の排他ロックが要求されると、トランザクション A が終了し、保持されている行 1 の共有ロックが解放されるまで B はブロックされます。
トランザクション A は、トランザクション B が完了するまで完了できませんが、トランザクション B もトランザクション A によってブロックされます。この状態は、循環依存関係とも呼ばれます。トランザクション A がトランザクション B に依存し、トランザクション B がトランザクション A に依存するため、依存関係が循環します。
デッドロック状態になったどちらのトランザクションも、外部処理によってデッドロックを解除されない限り、永久に待機を続けます。 データベース エンジンのデッドロック モニターは、デッドロックが発生しているタスクを定期的にチェックします。 モニターによって循環依存関係が検出されると、一方のタスクがデッドロックの犠牲者として選択され、そのトランザクションはエラーで終了されます。 その結果、もう一方のタスクのトランザクションを完了できます。 トランザクションがエラーで終了したアプリケーションは、そのトランザクションを再試行できます。通常は、一方のデッドロックのトランザクションが完了してからこのトランザクションも完了します。
デッドロックが、通常のブロッキングと混同されることがあります。 あるトランザクションが、別のトランザクションによってロックされているリソースのロックを要求すると、ロックを要求したトランザクションはロックが解放されるまで待機します。 既定では、 LOCK_TIMEOUT が設定されていない限り、データベース エンジン内のトランザクションはタイムアウトしません。 この場合、要求したトランザクションはブロックされているだけで、デッドロックが発生しているわけではありません。つまり、要求したトランザクションは、ロックを所有しているトランザクションをブロックする操作を行っていません。 最終的には、ロックを所有しているトランザクションが完了してロックが解放され、要求したトランザクションがロックを取得し、続行されます。 デッドロックはほぼ直ちに解決されますが、ブロッキングは理論的には無期限に続く可能性があります。 デッドロックは、「破壊的な支配」と呼ばれることもあります。
デッドロック状態は、リレーショナル データベース管理システムだけでなく、複数のスレッドを使用していれば、どのようなシステムでも発生する可能性があります。また、データベース オブジェクトのロック以外でもリソースで発生する可能性があります。 たとえば、マルチスレッド オペレーティング システムの 1 つのスレッドが、メモリのブロックなど、1 つ以上のリソースを取得するとします。 取得しようとしているリソースが別のスレッドに所有されている場合、最初のスレッドはリソースを所有しているスレッドがターゲットとするリソースを解放するまで待機することになります。 このとき、待機しているスレッドのことを「そのリソースについて、所有側のスレッドに対する依存関係がある」といいます。 データベース エンジンのインスタンスでは、メモリやスレッドなど、データベース以外のリソースを取得するときにセッションがデッドロックする可能性があります。
この例では、トランザクション T1 は Part テーブルのロック リソースに関して、トランザクション T2 に依存関係があります。 同様に、 Supplier テーブルのロック リソースに関しては、トランザクション T2 がトランザクション T1 に対する依存関係を持っています。 これらの依存関係は相互に働くため、トランザクション T1 と T2 の間でデッドロックが発生します。
デッドロックのより一般的な図を次に示します。
タスク T1 は、リソース R1 のロックを所有し (R1 から T1 への矢印で表しています)、リソース R2 のロックを要求しました (T1 から R2 への矢印で表しています)。
タスク T2 は、リソース R2 のロックを所有し (R2 から T2 への矢印で表しています)、リソース R1 のロックを要求しました (T2 から R1 への矢印で表しています)。
どちらのタスクもリソースが使用できるようになるまで続行できず、どちらのリソースもタスクが続行するまで解放できないため、デッドロック状態が発生します。
Note
データベース エンジンは、デッドロック サイクルを自動的に検出します。 トランザクションの 1 つをデッドロックの対象として選択し、デッドロックを中断するためにエラーで終了します。
デッドロックの原因となるリソース
各ユーザー セッションに含まれている 1 つ以上のタスクが、そのセッションのためにリソースを取得したり、リソースを取得するために待機状態にある場合があります。 次のような種類のリソースは、デッドロックの原因となるブロッキングを発生させる可能性があります。
Locks. オブジェクト、ページ、行、メタデータ、アプリケーションなどのリソースに対してロック取得のために待機していると、デッドロックが発生する場合があります。 たとえば、トランザクション T1 には行 r1 に対する共有 (
S) ロックがあり、r2 の排他 (X) ロックの取得を待機しています。 トランザクション T2 には r2 の共有 (S) ロックがあり、行 r1 の排他 (X) ロックの取得を待機しています。 この結果、T1 と T2 では、互いにロックされているリソースが解放されるのを待機するロック サイクルが発生します。ワーカー スレッド。 キューに登録されたタスクが利用可能なワーカー スレッドを待機していると、デッドロックが発生する場合があります。 キューに登録されたタスクが、ワーカー スレッドをすべてブロックしているリソースを所有している場合、デッドロックが発生します。 たとえば、セッション S1 はトランザクションを開始し、行 r1 で共有 (
S) ロックを取得してからスリープ状態になります。 使用可能なすべてのワーカー スレッドで実行されているアクティブなセッションは、行 r1 で排他 (X) ロックを取得しようとしています。 セッション S1 ではワーカー スレッドを取得できないので、トランザクションをコミットして行 r1 のロックを解放することができません。 この結果、デッドロックが発生します。Memory. 同時要求で使用できるメモリ量以上のメモリ許可を待機している場合、デッドロックが発生することがあります。 たとえば、2 つの同時実行クエリ Q1 と Q2 は、それぞれ 10 MB と 20 MB のメモリを取得するユーザー定義関数として実行されます。 各クエリで 30 MB が必要でも、使用できるメモリの合計が 20 MB の場合、Q1 および Q2 では、互いにメモリが解放されるまで待機する必要があります。その結果、デッドロックが発生します。
並列クエリ実行関連のリソース。 交換ポートに関連付けられたコーディネーター、プロデューサー、またはコンシューマーのスレッドが互いをブロックし、デッドロックを発生させることがあります。通常、この現象は、並列クエリに含まれていない別のプロセスを 1 つ以上含めようとした場合に発生します。 また、並列クエリの実行が開始されると、データベース エンジンは、現在のワークロードに基づいて並列処理の程度と必要なワーカー スレッドの数を決定します。 たとえば、サーバーで新しいクエリの実行が開始されたり、システムのワーカー スレッドが不足したりするなど、システムのワークロードが予期せず変更される場合は、デッドロックが発生する可能性があります。
複数のアクティブな結果セット (MARS) のリソース。 これらのリソースは、MARS でアクティブな複数の要求のインターリーブを制御する際に使用します。 詳しくは、 SQL Server Native Client の複数のアクティブな結果セット (MARS)を参照してください。
ユーザー リソース。 ユーザー アプリケーションで制御されている可能性のあるリソースをスレッドが待機している場合、そのリソースは、外部リソースまたはユーザー リソースと見なされ、ロックと同様に処理されます。
セッション ミューテックス。 1 つのセッションで実行中のタスクはインターリーブされます。つまり、セッションでは、一度に 1 つのタスクしか実行できません。 タスクを実行する前に、セッション ミューテックスに排他でアクセスする必要があります。
トランザクション ミューテックス。 1 つのトランザクションで実行中のすべてのタスクはインターリーブされます。つまり、トランザクションでは、一度に 1 つのタスクしか実行できません。 タスクを実行する前に、トランザクション ミューテックスに排他でアクセスする必要があります。
タスクを MARS で実行するには、セッション ミューテックスを取得する必要があります。 タスクがトランザクションで実行されている場合は、トランザクション ミューテックスを取得する必要があります。 これにより、そのセッションやトランザクションでは、一度に 1 つのタスクだけがアクティブになります。 必要なミューテックスを取得後に、タスクを実行できます。 タスクが終了するか、または要求の途中で中断されると、取得とは逆の順序で、最初にトランザクション ミューテックスが解放され、次にセッション ミューテックスが解放されます。 ただし、これらのリソースでデッドロックが発生する場合があります。 次の pseudocode では、ユーザーの要求 U1 と U2 という 2 つのタスクが同じセッション内で実行されています。
U1: Rs1=Command1.Execute("insert sometable EXEC usp_someproc"); U2: Rs2=Command2.Execute("select colA from sometable");ユーザーの要求 U1 で実行されているストアド プロシージャで、セッション ミューテックスが取得されています。 ストアド プロシージャの実行に時間がかかる場合は、ストアド プロシージャがユーザーからの入力を待機しているとデータベース エンジンによって想定されます。 ユーザーの要求 U2 ではセッション ミューテックスが解放されるのを待機しているのに対し、ユーザーは U2 の結果セットが返されるのを待機しています。さらに、U1 では、ユーザー リソースが解放されるのを待機しています。 次の図に、このデッドロック状態を論理的に示します。
デッドロックは、テーブルがパーティション分割されており、 LOCK_ESCALATION の ALTER TABLE 設定が AUTOに設定されている場合にも発生することがあります。
LOCK_ESCALATIONを AUTO に設定すると、データベース エンジンがテーブル レベルではなく HoBT レベルでテーブル パーティションをロックできるようにすることで、コンカレンシーが向上します。 ただし、個々のトランザクションがテーブルのパーティション ロックを保持し、他のトランザクション パーティションのどこかをロックする必要がある場合、デッドロックが発生します。 この種類のデッドロック状態は、 LOCK_ESCALATION を TABLEに設定することで回避できます。 ただし、この設定では、テーブル ロックを待機するようにパーティションに大幅な更新を強制することで、コンカレンシーが低下します。
デッドロック検出
「 デッドロック可能 なリソース」セクションにリストされているすべてのリソースは、データベース エンジンのデッドロック検出スキームに参加します。 デッドロック検出は、データベース エンジンのインスタンス内のすべてのタスクを定期的に検索を開始するロック モニター スレッドによって実行されます。 検索プロセスは次のとおりです。
既定の間隔は 5 秒です。
ロック モニター スレッドでデッドロックが検出されると、デッドロック検出の間隔は、デッドロックの頻度に応じて、5 秒から短くなります。最短の間隔は 100 ミリ秒です。
ロック モニター スレッドがデッドロックの検出を停止すると、データベース エンジンは検索間隔を 5 秒に増やします。
デッドロックが検出された場合、ロックを待機する必要がある新しいスレッドがデッドロック サイクルに入っていると見なされます。 デッドロックが検出された直後の最初の数回のロック待機では、次のデッドロックの検出間隔まで待機せず、すぐにデッドロックの検索が開始されます。 たとえば、検索の間隔が 5 秒に設定されている場合にデッドロックが検出されると、次のロック待機により、直ちにデッドロックの検出が開始されます。 このロック待機がデッドロックの一部である場合は、次のデッドロック検索中ではなく、すぐに検出されます。
通常、データベース エンジンは定期的なデッドロック検出のみを実行します。 通常、システムで発生するデッドロックの数は少ないため、定期的なデッドロック検出は、システムでのデッドロック検出のオーバーヘッドを軽減するのに役立ちます。
ロック モニターで、特定のスレッドに対するデッドロック検出が開始されると、スレッドが待機中のリソースが特定されます。 その後、ロック モニターでは、その特定のリソースを所有するスレッドが検出され、サイクルを検出するまで、スレッドのデッドロック検出が繰り返されます。 このように検出された相互の従属性により、デッドロックが発生します。
デッドロックが検出されると、データベース エンジンは、いずれかのスレッドをデッドロックの対象として選択してデッドロックを終了します。 データベース エンジンは、スレッドに対して実行されている現在のバッチを終了し、デッドロックの対象のトランザクションをロールバックして、エラー 1205 をアプリケーションに返します。 デッドロックの対象のトランザクションをロールバックすると、そのトランザクションで保持されていたすべてのロックが解放されます。 ロックが解放されると、他のスレッドのトランザクションのブロックは解除され、処理を続行することができるようになります。 1205 (デッドロックの対象) エラーは、デッドロックに関連するリソースの種類に関する情報を記録します。
既定では、データベース エンジンは、デッドロックの対象としてロールバックするコストが最も低いトランザクションを実行しているトランザクションを選択します。 また、ユーザーは、SET DEADLOCK_PRIORITY ステートメントを使用して、デッドロックが発生した場合のセッションの優先度を指定することもできます。
DEADLOCK_PRIORITY は、 LOW、 NORMAL、または HIGHに設定することも、または -10 から 10 の範囲の任意の整数値に設定することもできます。 場合によっては、データベース エンジンは、コンカレンシーを向上させるために、短時間デッドロックの優先度を変更することを選択する場合があります。
デッドロックの優先度は、既定で NORMAL または 0 になります。 2 つのセッションでデッドロックの優先順位が異なる場合は、優先順位の低いセッションのトランザクションがデッドロックの影響を受ける側として選択されます。 両方のセッションが同じデッドロック優先度を持つ場合は、ロールバックに最もコストのかからないトランザクションが選択されます。 デッドロック サイクルに関連するセッションのデッドロックの優先度とコストが同じ場合、対象はランダムに選択されます。 ロールバックを実行中のタスクは、デッドロックの対象として選択できません。
共通言語ランタイム (CLR) を使用する場合、デッドロック モニターは、マネージド プロシージャ内でアクセスされた同期リソース (モニター、リーダー/ライター ロック、スレッド結合) のデッドロックを自動的に検出します。 ただし、デッドロックは、デッドロックの対象として選択されたプロシージャに例外をスローすることによって解決されます。 デッドロックの対象が現在所有しているリソースは、この例外により自動的に解放されないことに注意してください。つまり、リソースは明示的に解放する必要があります。 例外の動作と一貫性があるため、デッドロックの対象の特定に使用された例外は、キャッチおよび破棄できます。
デッドロック情報ツール
デッドロック情報を表示するために、データベース エンジンは、 xml_deadlock_report 拡張イベント、2 つのトレース フラグ、および SQL Profiler のデッドロック グラフ イベントの形式で監視ツールを提供します。
xml_deadlock_report拡張イベントは、デッドロック情報をキャプチャするための推奨される方法です。
デッドロック拡張イベント
SQL Server 2012 (11.x) 以降のバージョンでは、SQL トレースまたは SQL Profiler のデッドロック グラフ イベント クラスの代わりに、 xml_deadlock_report 拡張イベントを使用する必要があります。
system_health イベント セッションは、既定でxml_deadlock_reportイベントをキャプチャします。 これらのイベントにはデッドロック グラフが含まれています。
system_health セッションは既定で有効になっているため、デッドロック情報をキャプチャするために別のイベント セッションを構成する必要はありません。
通常キャプチャされる Deadlock Graph には、3 つの個別のノードがあります。
-
victim-list。 デッドロック犠牲者プロセス識別子。 -
process-list。 デッドロックに関係するすべてのプロセスについての情報。 -
resource-list。 デッドロックに関係するリソースについての情報。
Management Studio で、event_file セッションのsystem_healthターゲット データを表示できます。
xml_deadlock_reportイベントが発生した場合、次の例に示すように、Management Studio はデッドロックに関連するタスクとリソースをグラフィカルに示します。
次のクエリでは、ring_buffer セッションのsystem_health ターゲットによってキャプチャされたすべてのデッドロック イベントを表示できます。
SELECT xdr.value('@timestamp', 'datetime') AS deadlock_time,
xdr.query('.') AS event_data
FROM (SELECT CAST ([target_data] AS XML) AS target_data
FROM sys.dm_xe_session_targets AS xt
INNER JOIN sys.dm_xe_sessions AS xs
ON xs.address = xt.event_session_address
WHERE xs.name = N'system_health'
AND xt.target_name = N'ring_buffer') AS XML_Data
CROSS APPLY Target_Data.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData(xdr)
ORDER BY deadlock_time DESC;
結果セットは次のとおりです。
次の例は、 event_data 列からの出力の例を示しています。
<event name="xml_deadlock_report" package="sqlserver" timestamp="2022-02-18T08:26:24.698Z">
<data name="xml_report">
<type name="xml" package="package0" />
<value>
<deadlock>
<victim-list>
<victimProcess id="process27b9b0b9848" />
</victim-list>
<process-list>
<process id="process27b9b0b9848" taskpriority="0" logused="0" waitresource="KEY: 5:72057594214350848 (1a39e6095155)" waittime="1631" ownerId="11088595" transactionname="SELECT" lasttranstarted="2022-02-18T00:26:23.073" XDES="0x27b9f79fac0" lockMode="S" schedulerid="9" kpid="15336" status="suspended" spid="62" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2022-02-18T00:26:22.893" lastbatchcompleted="2022-02-18T00:26:22.890" lastattention="1900-01-01T00:00:00.890" clientapp="SQLCMD" hostname="ContosoServer" hostpid="7908" loginname="CONTOSO\user" isolationlevel="read committed (2)" xactid="11088595" currentdb="5" lockTimeout="4294967295" clientoption1="538968096" clientoption2="128056">
<executionStack>
<frame procname="AdventureWorks2022.dbo.p1" line="3" stmtstart="78" stmtend="180" sqlhandle="0x0300050020766505ca3e07008ba8000001000000000000000000000000000000000000000000000000000000">
SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+ </frame>
<frame procname="adhoc" line="4" stmtstart="82" stmtend="98" sqlhandle="0x020000006263ec01ebb919c335024a072a2699958d3fcce60000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
SET NOCOUNT ON
WHILE (1=1)
BEGIN
EXEC p1 4
END
</inputbuf>
</process>
<process id="process27b9ee33c28" taskpriority="0" logused="252" waitresource="KEY: 5:72057594214416384 (e5b3d7e750dd)" waittime="1631" ownerId="11088593" transactionname="UPDATE" lasttranstarted="2022-02-18T00:26:23.073" XDES="0x27ba15a4490" lockMode="X" schedulerid="6" kpid="5584" status="suspended" spid="58" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2022-02-18T00:26:22.890" lastbatchcompleted="2022-02-18T00:26:22.890" lastattention="1900-01-01T00:00:00.890" clientapp="SQLCMD" hostname="ContosoServer" hostpid="15316" loginname="CONTOSO\user" isolationlevel="read committed (2)" xactid="11088593" currentdb="5" lockTimeout="4294967295" clientoption1="538968096" clientoption2="128056">
<executionStack>
<frame procname="AdventureWorks2022.dbo.p2" line="3" stmtstart="76" stmtend="150" sqlhandle="0x03000500599a5906ce3e07008ba8000001000000000000000000000000000000000000000000000000000000">
UPDATE t1 SET c2 = c2+1 WHERE c1 = @p </frame>
<frame procname="adhoc" line="4" stmtstart="82" stmtend="98" sqlhandle="0x02000000008fe521e5fb1099410048c5743ff7da04b2047b0000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
SET NOCOUNT ON
WHILE (1=1)
BEGIN
EXEC p2 4
END
</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594214350848" dbid="5" objectname="AdventureWorks2022.dbo.t1" indexname="cidx" id="lock27b9dd26a00" mode="X" associatedObjectId="72057594214350848">
<owner-list>
<owner id="process27b9ee33c28" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process27b9b0b9848" mode="S" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594214416384" dbid="5" objectname="AdventureWorks2022.dbo.t1" indexname="idx1" id="lock27afa392600" mode="S" associatedObjectId="72057594214416384">
<owner-list>
<owner id="process27b9b0b9848" mode="S" />
</owner-list>
<waiter-list>
<waiter id="process27b9ee33c28" mode="X" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</value>
</data>
</event>
トレース フラグ 1204 およびトレース フラグ 1222
デッドロックが発生し、トレース フラグ 1204 またはトレース フラグ 1222 が有効になっている場合、デッドロックの詳細が SQL Server エラー ログに報告されます。 トレース フラグ 1204 は、デッドロックに関係する各ノードによって書式設定されたデッドロック情報を報告します。 トレース フラグ 1222 は、まずプロセスごとに、次にリソースごとにデッドロック情報を書式設定します。 両方のトレース フラグを有効にして、同じデッドロック イベントを 2 種類の表明で取得することも可能です。
Important
デッドロックが発生しているワークロード集中型システムでは、トレース フラグ 1204 と 1222 を使用しないでください。 これらのトレースフラグを使用すると、パフォーマンスの問題が発生する可能性があります。 代わりに、 Deadlock 拡張イベント を使用して、必要な情報をキャプチャします。
トレース フラグ 1204 と 1222 のプロパティの定義に加えて、次の表に類似点と相違点も示します。
| Property | トレース フラグ 1204 およびトレース フラグ 1222 | トレース フラグ 1204 のみ | トレース フラグ 1222 のみ |
|---|---|---|---|
| 出力形式 | 出力は SQL Server のエラー ログにキャプチャされます。 | デッドロックに関係するノードだけが表示されます。 各ノードには専用のセクションがあり、最後のセクションではデッドロック対象が示されます。 | XML スキーマ定義 (XSD) スキーマには準拠していない、XML に似た形式で情報を返します。 この形式には、3 つの主要なセクションがあります。 最初のセクションでは、デッドロック対象が宣言されます。 2 番目のセクションでは、デッドロックに関係する各プロセスが示されます。 3 番目のセクションでは、トレース フラグ 1204 のノードと同義のリソースについて説明します。 |
| 属性の識別 |
SPID:<x> ECID:<x>. 並列プロセスの場合にセッション ID スレッドを識別します。 エントリ SPID:<x> ECID:0 ( <x> は SPID 値に置き換えられます) は、メイン スレッドを表します。
SPID:<x> ECID:<y>が SPID 値に置き換えられ、<x>が 0 より大きいエントリ <y>は、同じ SPID の実行コンテキストを表します。BatchID(sbidトレース フラグ 1222 用) コードの実行でロックを要求または保持しているバッチを識別します。 複数のアクティブな結果セット (MARS) が無効になっている場合、BatchID の値は 0 になります。 MARS が有効になっている場合、アクティブなバッチの値は 1 から n になります。 セッションにアクティブなバッチが存在しない場合、BatchID は 0 になります。Mode スレッドによって要求、許可、または待機される特定のリソースに対して、ロックの種類を指定します。 モードには、Intent Shared (IS)、Shared (S)、Update (U)、Intent Exclusive (IX)、Shared with Intent Exclusive (SIX)、Exclusive (X) を指定できます。Line #(lineトレース フラグ 1222 用) デッドロックが発生したときに実行されていた、現在のステートメントのバッチの行番号が表示されます。Input Buf(inputbufトレース フラグ 1222 用) 現在のバッチに含まれるステートメントをすべて表示します。 |
Node デッドロック チェーンに含まれるエントリ番号を表します。Lists 次の一覧にロックの所有者が含まれる場合があります。Grant List リソースの現在の所有者を列挙します。Convert List ロックを高いレベルに変換しようとしている現在の所有者を列挙します。Wait List リソースに対する現在の新しいロック要求を列挙します。Statement Type スレッドにアクセス許可があるステートメントの種類 (SELECT、 INSERT、 UPDATE、または DELETE) について説明します。Victim Resource Owner データベース エンジンがデッドロック サイクルを中断する対象として選択する参加スレッドを指定します。 選択したスレッドとそのすべての実行コンテキストが終了します。Next Branch デッドロック サイクルに関係する同じ SPID からの 2 つ以上の実行コンテキストを表します。 |
deadlock victim デッドロックの対象として選択されたタスクの物理メモリ アドレス ( sys.dm_os_tasksを参照) を表します。 未解決のデッドロックの場合、値は 0 になる可能性があります。executionstack デッドロックが発生したときに実行される Transact-SQL 呼び出し履歴を表します。priority デッドロックの優先度を表します。logused タスクで使用されているログ領域です。owner id 要求を制御するトランザクションの ID です。status タスクの状態です。 詳細については、「sys.dm_os_tasks」 を参照してください。waitresource タスクで必要なリソースです。waittime リソースを待機する時間 (ミリ秒単位) です。schedulerid このタスクに関連付けられているスケジューラ。
sys.dm_os_schedulersを参照してください。hostname ワークステーションの名前です。isolationlevel 現在のトランザクション分離レベルです。Xactid 要求を制御するトランザクションの ID です。currentdb データベースの ID です。lastbatchstarted クライアント プロセスで最後にバッチ実行が開始した時刻です。lastbatchcompleted クライアント プロセスで最後にバッチ実行が完了した時刻です。clientoption1 と clientoption2 このセッションの設定オプション。 これらの値は、通常、SETやSET NOCOUNTなどのSET XACTABORTステートメントによって制御されるオプションを表すビットマスクです。 詳細については、「 @@OPTIONS」を参照してください。associatedObjectId HoBT (ヒープまたは B ツリー) の ID を表します。 |
| リソース属性 |
RID はロックが保持または要求されているテーブル内の単一行を識別します。 RID は RID: db_id:file_id:page_no:row_no として表されます。 たとえば、「 RID: 6:1:20789:0 」のように入力します。OBJECT はロックが保持または要求されているテーブルを識別します。
OBJECT は OBJECT: db_id:object_idとして表されます。 たとえば、「 TAB: 6:2009058193 」のように入力します。KEY ロックが保持または要求されているインデックス内のキー範囲を識別します。 KEY は、KEY: db_id:hobt_id (インデックス キー ハッシュ値) として表されます。 たとえば、「 KEY: 6:72057594057457664 (350007a4d329) 」のように入力します。PAG ロックが保持または要求されているページ リソースを識別します。
PAG は PAG: db_id:file_id:page_noとして表されます。 たとえば、「 PAG: 6:1:20789 」のように入力します。EXT エクステント構造を識別します。
EXT は EXT: db_id:file_id:extent_noとして表されます。 たとえば、「 EXT: 6:1:9 」のように入力します。DB データベース ロックを識別します。
DB は次のいずれかで表されます。DB: db_idDB: db_id[BULK-OP-DB]: データベース バックアップによって取得されたデータベース ロックを識別します。DB: db_id[BULK-OP-LOG]は、ログ バックアップによって取得されたロックを識別します。APP アプリケーション ロックを識別します。
APP は APP: lock_resourceとして表されます。 たとえば、「 APP: Formf370f478 」のように入力します。METADATA デッドロックに関係するメタデータ リソースを表します。
METADATA には多数のサブリソースがあるため、返される値はデッドロックされたサブリソースに依存します。 たとえば、METADATA.USER_TYPE では user_type_id = *integer_value* が返されます。
METADATA のリソースおよびサブリソースについて詳しくは、 sys.dm_tran_locksを参照してください。HOBT デッドロックに関係するヒープまたは B ツリーを表します。 |
このトレース フラグに限定されるリソース属性はありません。 | このトレース フラグに限定されるリソース属性はありません。 |
トレース フラグ 1204 の例
次の例は、トレース フラグ 1204 が有効になっている場合の出力を示しています。 この場合、ノード 1 のテーブルはインデックスのないヒープ、ノード 2 のテーブルは非クラスター化インデックスのあるヒープになります。 ノード 2 のインデックス キーは、デッドロックの発生時に更新されます。
Deadlock encountered .... Printing deadlock information
Wait-for graph
Node:1
RID: 6:1:20789:0 CleanCnt:3 Mode:X Flags: 0x2
Grant List 0:
Owner:0x0315D6A0 Mode: X
Flg:0x0 Ref:0 Life:02000000 SPID:55 ECID:0 XactLockInfo: 0x04D9E27C
SPID: 55 ECID: 0 Statement Type: UPDATE Line #: 6
Input Buf: Language Event:
BEGIN TRANSACTION
EXEC usp_p2
Requested By:
ResType:LockOwner Stype:'OR'Xdes:0x03A3DAD0
Mode: U SPID:54 BatchID:0 ECID:0 TaskProxy:(0x04976374) Value:0x315d200 Cost:(0/868)
Node:2
KEY: 6:72057594057457664 (350007a4d329) CleanCnt:2 Mode:X Flags: 0x0
Grant List 0:
Owner:0x0315D140 Mode: X
Flg:0x0 Ref:0 Life:02000000 SPID:54 ECID:0 XactLockInfo: 0x03A3DAF4
SPID: 54 ECID: 0 Statement Type: UPDATE Line #: 6
Input Buf: Language Event:
BEGIN TRANSACTION
EXEC usp_p1
Requested By:
ResType:LockOwner Stype:'OR'Xdes:0x04D9E258
Mode: U SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0475E374) Value:0x315d4a0 Cost:(0/380)
Victim Resource Owner:
ResType:LockOwner Stype:'OR'Xdes:0x04D9E258
Mode: U SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0475E374) Value:0x315d4a0 Cost:(0/380)
トレース フラグ 1222 の例
次の例は、トレース フラグ 1222 が有効になっている場合の出力を示しています。 この場合、一方のテーブルがインデックスのないヒープになり、他方のテーブルが非クラスター化インデックスのあるヒープになります。 2 番目のテーブルでは、デッドロックの発生時にインデックス キーが更新されます。
deadlock-list
deadlock victim=process689978
process-list
process id=process6891f8 taskpriority=0 logused=868
waitresource=RID: 6:1:20789:0 waittime=1359 ownerId=310444
transactionname=user_transaction
lasttranstarted=2022-02-05T11:22:42.733 XDES=0x3a3dad0
lockMode=U schedulerid=1 kpid=1952 status=suspended spid=54
sbid=0 ecid=0 priority=0 transcount=2
lastbatchstarted=2022-02-05T11:22:42.733
lastbatchcompleted=2022-02-05T11:22:42.733
clientapp=Microsoft SQL Server Management Studio - Query
hostname=TEST_SERVER hostpid=2216 loginname=DOMAIN\user
isolationlevel=read committed (2) xactid=310444 currentdb=6
lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200
executionStack
frame procname=AdventureWorks2022.dbo.usp_p1 line=6 stmtstart=202
sqlhandle=0x0300060013e6446b027cbb00c69600000100000000000000
UPDATE T2 SET COL1 = 3 WHERE COL1 = 1;
frame procname=adhoc line=3 stmtstart=44
sqlhandle=0x01000600856aa70f503b8104000000000000000000000000
EXEC usp_p1
inputbuf
BEGIN TRANSACTION
EXEC usp_p1
process id=process689978 taskpriority=0 logused=380
waitresource=KEY: 6:72057594057457664 (350007a4d329)
waittime=5015 ownerId=310462 transactionname=user_transaction
lasttranstarted=2022-02-05T11:22:44.077 XDES=0x4d9e258 lockMode=U
schedulerid=1 kpid=3024 status=suspended spid=55 sbid=0 ecid=0
priority=0 transcount=2 lastbatchstarted=2022-02-05T11:22:44.077
lastbatchcompleted=2022-02-05T11:22:44.077
clientapp=Microsoft SQL Server Management Studio - Query
hostname=TEST_SERVER hostpid=2216 loginname=DOMAIN\user
isolationlevel=read committed (2) xactid=310462 currentdb=6
lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200
executionStack
frame procname=AdventureWorks2022.dbo.usp_p2 line=6 stmtstart=200
sqlhandle=0x030006004c0a396c027cbb00c69600000100000000000000
UPDATE T1 SET COL1 = 4 WHERE COL1 = 1;
frame procname=adhoc line=3 stmtstart=44
sqlhandle=0x01000600d688e709b85f8904000000000000000000000000
EXEC usp_p2
inputbuf
BEGIN TRANSACTION
EXEC usp_p2
resource-list
ridlock fileid=1 pageid=20789 dbid=6 objectname=AdventureWorks2022.dbo.T2
id=lock3136940 mode=X associatedObjectId=72057594057392128
owner-list
owner id=process689978 mode=X
waiter-list
waiter id=process6891f8 mode=U requestType=wait
keylock hobtid=72057594057457664 dbid=6 objectname=AdventureWorks2022.dbo.T1
indexname=nci_T1_COL1 id=lock3136fc0 mode=X
associatedObjectId=72057594057457664
owner-list
owner id=process6891f8 mode=X
waiter-list
waiter id=process689978 mode=U requestType=wait
Profiler の Deadlock Graph イベント
SQL Profiler には、デッドロックに関係するタスクとリソースをグラフィカルに示すイベントがあります。 次の例は、Deadlock Graph イベントがオンになっている場合の SQL Profiler からの出力を示しています。
SQL Profiler および SQL トレース機能は非推奨となり、拡張イベントに置き換えられます。 拡張イベントのパフォーマンス オーバーヘッドは小さく、SQL トレースよりも構成可能です。 SQL Profiler でデッドロックをトレースするのではなく、 拡張イベントのデッドロック イベント を使用することを検討してください。
デッドロック イベントの詳細については、「Lock:Deadlock Event Class」(Lock:Deadlock イベント クラス) を参照してください。 SQL Profiler デッドロック グラフの詳細については、「 デッドロック グラフの保存 (SQL Server Profiler)」を参照してください。
拡張イベントは、SQL トレース イベント クラスと同等の機能を提供します。 詳細については、「 SQL トレース イベント クラスと同等の拡張イベントを表示する」を参照してください。 拡張イベントは、SQL トレースよりも推奨されます。
デッドロックの処理
データベース エンジンのインスタンスがトランザクションをデッドロックの対象として選択すると、現在のバッチが終了され、トランザクションがロールバックされ、エラー 1205 がアプリケーションに返されます。 返されるメッセージは、次のように構成されます。
Your transaction (process ID #...) was deadlocked on {lock | communication buffer | thread} resources with another process and has been chosen as the deadlock victim. Rerun your transaction.
Transact-SQL クエリを送信するすべてのアプリケーションをデッドロックの対象として選択できるため、アプリケーションにはエラー 1205 を処理できるエラー ハンドラーが必要です。 アプリケーションでエラーが処理されない場合、アプリケーションはトランザクションがロールバックされたことを認識せずに続行できます。
エラー 1205 をキャッチするエラー ハンドラーを実装すると、アプリケーションはデッドロックを処理し、修復アクションを実行できます (たとえば、デッドロックに関連するクエリを自動的に再送信するなど)。
アプリケーションは、クエリを再送信する前に少しの間停止する必要があります。 これにより、デッドロックに関係する他のトランザクションがロックを完了して解放できるようになります。 一時停止の期間をランダム化すると、再送信されたクエリがロックを要求したときにデッドロックが繰り返される可能性が最小限に抑えられます。 たとえば、エラー ハンドラーは、1 秒から 3 秒間ランダムに一時停止するようにコーディングできます。
TRY...CATCH を使用して処理する
TRY...CATCH を使用してデッドロック状態を処理できます。 エラー 1205 は、 CATCH ブロックでキャッチできます。
詳細については、 デッドロックの処理を参照してください。
デッドロックを最小限に抑える
デッドロックを完全に回避することはできませんが、コーディング上の一定の規則に従うことにより、デッドロックが発生する可能性を最小限に抑えることができます。 デッドロックの発生数を抑えると、以下の理由から、トランザクションのスループットが向上し、システムのオーバーヘッドが減少します。
- ロールバック (トランザクションが実行したすべての処理の取り消し) の対象となるトランザクションの数が減少します。
- デッドロック後にロールバックされたトランザクションをアプリケーションが再実行する場合、対象となるトランザクションの数が減少します。
デッドロックを最小限に抑えるには、次の手順を実行します。
- 同じ順序でオブジェクトにアクセスします。
- トランザクション内でのユーザーとのやり取りを避けます。
- トランザクションを短くして 1 つのバッチ内に収めます。
- 必要でない場合は、
REPEATABLE READやSERIALIZABLEなどの分離レベルを高くしないでください。 - 行のバージョン管理に基づく分離レベルを使用します。
-
READ_COMMITTED_SNAPSHOT分離レベルを使用してトランザクションに行のバージョン管理を使用するには、READ COMMITTEDデータベース オプションを有効にします。 - スナップショット分離トランザクションを使用します。
-
- バインドされた接続を使用します。
同じ順序でのオブジェクトへのアクセス
すべての同時実行トランザクションが同じ順序でオブジェクトにアクセスすると、デッドロックの発生する可能性は低くなります。 たとえば、2 つの同時実行トランザクションが Supplier テーブルでロックを取得してから Part テーブルでロックを取得する場合、一方のトランザクションは、もう一方のトランザクションが完了するまで Supplier テーブルでブロックされます。 1 番目のトランザクションがコミットまたはロール バックされた後に 2 番目のトランザクションが続行されるので、デッドロックは発生しません。 すべてのデータ変更にストアド プロシージャを使用すると、オブジェクトへのアクセス順序を統一できます。
トランザクション内でのユーザーとのやり取りの回避
ユーザーの介入なしで実行されるバッチの速度は、アプリケーションによって要求されたパラメーターのプロンプトに応答するなど、ユーザーがクエリに手動で応答する必要がある速度よりもはるかに高速であるため、ユーザーの操作を含むトランザクションは避けてください。 トランザクションが保持するロックを解除するにはトランザクションのコミットまたはロールバックが必要なので、このような状況ではシステムのスループットが低下してしまいます。 デッドロックが発生しない場合でも、同じリソースにアクセスする他のトランザクションは、トランザクションの完了を待機している間にブロックされます。
トランザクションを短くして 1 つのバッチ内に収める
デッドロックは主に、同じデータベースで長時間動作するトランザクションがいくつか同時に実行されている場合に発生します。 トランザクションが長くなれば、排他ロックまたは更新ロックが長時間になり、他の処理をブロックしてしまうので、デッドロックが発生する可能性が高くなります。
トランザクションを 1 つのバッチに保持すると、トランザクション中のネットワークラウンドトリップが最小限に抑えられるため、クライアント処理によるトランザクションの完了の遅延が減ります。
分離レベルを上げないようにする
低い分離レベルでトランザクションが実行可能かどうかを調べます。
READ COMMITTEDを使用すると、トランザクションは、トランザクションが完了するのを待たずに、別のトランザクションによって以前に読み取られた (変更されていない) データを読み取ることができます。
READ COMMITTED は、 SERIALIZABLEなど、より高い分離レベルよりも短い期間、共有ロックを保持します。 これにより、ロックの競合が減少します。
行のバージョン管理に基づく分離レベルの使用
READ_COMMITTED_SNAPSHOT データベース オプションがON設定されている場合、READ COMMITTED分離レベルで実行されているトランザクションでは、読み取り操作中に共有ロックではなく、行のバージョン管理が使用されます。
ヒント
Microsoft では、アプリケーションがロックベースのREAD COMMITTED分離レベルのブロック動作に依存しない限り、すべてのアプリケーションに対して行のバージョン管理ベースのREAD COMMITTED分離レベルを推奨しています。
スナップショット分離レベルでも行のバージョン管理を使用します。行のバージョン管理では、読み取り操作中に共有ロックを使用しません。 スナップショット分離レベルでトランザクションを実行する前に、 ALLOW_SNAPSHOT_ISOLATION データベース オプションを ONに設定する必要があります。
行のバージョン管理ベースの分離レベルを使用して、読み取り操作と書き込み操作の間に発生する可能性があるデッドロックを最小限に抑えます。
バインドされた接続の使用
バインドされた接続を使用すると、同じアプリケーションによって開かれた複数の接続が相互に協調動作できます。 最初の接続が取得したロックと同じように次の接続が取得したロックも保持されます。また、その逆の場合も同様に保持されます。 したがって、互いをブロックすることはありません。
デッドロックの原因
学習またはデモンストレーションの目的でデッドロックを引き起こす必要がある場合があります。
次の例は、READ_COMMITTED_SNAPSHOTAdventureWorksLT2019場合に、既定のスキーマとデータを使用して、サンプル データベースで動作します。 このサンプルをダウンロードするには、 AdventureWorks サンプル データベースにアクセスしてください。
最適化されたロックが有効な場合にデッドロックが発生する例については、「 最適化されたロックとデッドロック」を参照してください。
デッドロックを引き起こすには、2 つのセッションを AdventureWorksLT2019 データベースに接続する必要があります。 これらのセッションはセッション A と セッション B と言います。SQL Server Management Studio (SSMS) で 2 つのクエリ ウィンドウを作成することで、これら 2 つのセッションを作成できます。
セッション A で、次のバッチを実行します。 このコードは 、明示的なトランザクション を開始し、 SalesLT.Product テーブルを更新するステートメントを実行します。 これを行うために、トランザクションはテーブルの修飾行に対するSalesLT.Productを取得し、その後排他 (X) ロックに変換します。 トランザクションは開いたままにします。
BEGIN TRANSACTION;
UPDATE SalesLT.Product
SET SellEndDate = SellEndDate + 1
WHERE Color = 'Red';
次に、 セッション B で次のバッチを実行します。 このコードは、トランザクションを明示的に開始しません。 代わりに、オートコミット トランザクション モードで動作します。 このステートメントは、SalesLT.ProductDescription テーブルを更新します。 更新プログラムは、U テーブル内の該当する行に対して更新 (SalesLT.ProductDescription) ロックを取得します。 クエリは、テーブルを含む他のテーブルに SalesLT.Product 結合されます。
UPDATE SalesLT.ProductDescription
SET Description = Description
FROM SalesLT.ProductDescription AS pd
INNER JOIN SalesLT.ProductModelProductDescription AS pmpd
ON pd.ProductDescriptionID = pmpd.ProductDescriptionID
INNER JOIN SalesLT.ProductModel AS pm
ON pmpd.ProductModelID = pm.ProductModelID
INNER JOIN SalesLT.Product AS p
ON pm.ProductModelID = p.ProductModelID
WHERE p.Color = 'Silver';
この更新を完了するには、セッション B は、セッション S によってロックされている行を含め、テーブル SalesLT.Product内の行に対する共有 () ロックを必要とします。セッション B は、SalesLT.Productでブロックされます。
セッション A に戻ります。次のUPDATEステートメントを実行します。 このステートメントは、以前に開かれたトランザクションの一部として実行されます。
UPDATE SalesLT.ProductDescription
SET Description = Description
FROM SalesLT.ProductDescription AS pd
INNER JOIN SalesLT.ProductModelProductDescription AS pmpd
ON pd.ProductDescriptionID = pmpd.ProductDescriptionID
INNER JOIN SalesLT.ProductModel AS pm
ON pmpd.ProductModelID = pm.ProductModelID
INNER JOIN SalesLT.Product AS p
ON pm.ProductModelID = p.ProductModelID
WHERE p.Color = 'Red';
セッション A の 2 番目の更新ステートメントは、 の セッション B SalesLT.ProductDescriptionによってブロックされます。
セッション A と セッション B が相互にブロックし合うようになりました。 どちらのトランザクションも、それぞれが他方によってロックされているリソースを必要とするため、続行できません。
数秒後、デッドロック モニターは、 セッション A と セッション B のトランザクションが相互にブロックし合っており、どちらも進行できないことを識別します。 デッドロックが発生し、 セッション A がデッドロックの被害者として選択されていることがわかります。 セッション B が正常に完了します。 セッション A のクエリ ウィンドウに、次の例のようなテキストを含むエラー メッセージが表示されます。
Msg 1205, Level 13, State 51, Line 7
Transaction (Process ID 51) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
デッドロック状態が発生しない場合は、サンプル データベースで READ_COMMITTED_SNAPSHOT が有効になっていることを確認します。 デッドロック状態は任意のデータベース構成で発生する可能性がありますが、この例では READ_COMMITTED_SNAPSHOT を有効にする必要があります。
ring_buffer イベント セッションのsystem_healthターゲットでデッドロックの詳細を表示できます。これは、SQL Server と Azure SQL Managed Instance で既定で有効およびアクティブになっています。 次のクエリがあるとします。
WITH cteDeadLocks ([Deadlock_XML])
AS (SELECT CAST (target_data AS XML) AS [Deadlock_XML]
FROM sys.dm_xe_sessions AS xs
INNER JOIN sys.dm_xe_session_targets AS xst
ON xs.[address] = xst.event_session_address
WHERE xs.[name] = 'system_health'
AND xst.target_name = 'ring_buffer')
SELECT x.Graph.query('(event/data/value/deadlock)[1]') AS Deadlock_XML,
x.Graph.value('(event/data/value/deadlock/process-list/process/@lastbatchstarted)[1]', 'datetime2(3)') AS when_occurred,
DB_Name(x.Graph.value('(event/data/value/deadlock/process-list/process/@currentdb)[1]', 'int')) AS DB --Current database of the first listed process
FROM (SELECT Graph.query('.') AS Graph
FROM cteDeadLocks AS c
CROSS APPLY c.[Deadlock_XML].nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS Deadlock_Report(Graph)) AS x
ORDER BY when_occurred DESC;
HYPERLINK として表示されるセルを選択すると、SSMS 内の Deadlock_XML 列に XML を表示できます。 この出力を .xdl ファイルとして保存し、閉じてから SSMS で .xdl ファイルを開き直して、視覚的なデッドロック グラフを表示します。 デッドロック グラフは、次の図のようになります。
最適化されたロックとデッドロック
最適化されたロックでは、ページロックと行ロックはトランザクションの終了まで保持されません。 これらは、行が更新されるとすぐにリリースされます。 さらに、 READ_COMMITTED_SNAPSHOT が有効になっている場合、更新 (U) ロックは使用されません。 その結果、デッドロックの可能性が低下します。
前の例では、更新 (U) ロックに依存しているため、最適化されたロックが有効になっている場合はデッドロックは発生しません。
次の例を使用すると、最適化されたロックが有効になっているデータベースでデッドロックを発生させることができます。
まず、サンプル テーブルを作成し、データを追加します。
CREATE TABLE t2
(
a INT PRIMARY KEY NOT NULL,
b INT NULL
);
INSERT INTO t2
VALUES (1, 10),
(2, 20),
(3, 30);
次の T-SQL バッチは、2 つの別々のセッションで順番に実行され、デッドロックを作成します。
セッション 1 内:
BEGIN TRANSACTION xactA;
UPDATE t2
SET b = b + 10
WHERE a = 1;
セッション 2 内:
BEGIN TRANSACTION xactB;
UPDATE t2
SET b = b + 10
WHERE a = 2;
セッション 1 内:
UPDATE t2
SET b = b + 100
WHERE a = 2;
セッション 2 内:
UPDATE t2
SET b = b + 20
WHERE a = 1;
この場合、各セッションは独自のトランザクション ID (TID) リソースに対して排他 (X) ロックを保持し、他の TID の共有 (S) ロックを待機しています。その結果、デッドロックが発生します。
次の省略されたデッドロック レポートには、最適化されたロックに固有の要素と属性が含まれています。 デッドロック レポート <resource-list>内の各リソースの下で、各 <xactlock> 要素は、デッドロックの各メンバーの基になるリソースと TID ロック情報を報告します。
<deadlock>
<victim-list>
<victimProcess id="process12994344c58" />
</victim-list>
<process-list>
<process id="process12994344c58" taskpriority="0" logused="272" waitresource="XACT: 23:2476:0 KEY: 23:72057594049593344 (8194443284a0)" waittime="447" ownerId="3234906" transactionname="xactA" lasttranstarted="2025-10-08T21:36:34.063" XDES="0x12984ba0480" lockMode="S" schedulerid="2" kpid="204928" status="suspended" spid="95" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2025-10-08T21:36:40.857" lastbatchcompleted="2025-10-08T21:36:34.063" lastattention="2025-10-08T21:36:11.340" clientapp="Microsoft SQL Server Management Studio - Query" hostname="WS1" hostpid="23380" loginname="user1" isolationlevel="read committed (2)" xactid="3234906" currentdb="23" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
<inputbuf>
UPDATE t2
SET b = b + 20
WHERE a = 1;
</inputbuf>
</process>
<process id="process1299c969828" taskpriority="0" logused="272" waitresource="XACT: 23:2477:0 KEY: 23:72057594049593344 (61a06abd401c)" waittime="3083" ownerId="3234886" transactionname="xactB" lasttranstarted="2025-10-08T21:36:30.303" XDES="0x12995c84480" lockMode="S" schedulerid="2" kpid="63348" status="suspended" spid="88" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2025-10-08T21:36:38.223" lastbatchcompleted="2025-10-08T21:36:30.303" lastattention="1900-01-01T00:00:00.303" clientapp="Microsoft SQL Server Management Studio - Query" hostname="WS1" hostpid="23380" loginname="user1" isolationlevel="read committed (2)" xactid="3234886" currentdb="23" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
<inputbuf>
UPDATE t2
SET b = b + 100
WHERE a = 2;
</inputbuf>
</process>
</process-list>
<resource-list>
<xactlock xdesIdLow="2476" xdesIdHigh="0" dbid="23" id="lock1299fa06c00" mode="X">
<UnderlyingResource>
<keylock hobtid="72057594049593344" dbid="23" objectname="e6fc405e-1ee8-49df-a2b3-54ee0151d851.dbo.t2" indexname="PK__t2__3BD0198ED3CBA65E" />
</UnderlyingResource>
<owner-list>
<owner id="process1299c969828" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process12994344c58" mode="S" requestType="wait" />
</waiter-list>
</xactlock>
<xactlock xdesIdLow="2477" xdesIdHigh="0" dbid="23" id="lock129940b2380" mode="X">
<UnderlyingResource>
<keylock hobtid="72057594049593344" dbid="23" objectname="e6fc405e-1ee8-49df-a2b3-54ee0151d851.dbo.t2" indexname="PK__t2__3BD0198ED3CBA65E" />
</UnderlyingResource>
<owner-list>
<owner id="process12994344c58" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process1299c969828" mode="S" requestType="wait" />
</waiter-list>
</xactlock>
</resource-list>
</deadlock>
関連コンテンツ
- 拡張イベントの概要
- sys.dm_tran_locks (Transact-SQL)
- Deadlock Graph イベント クラス
- Read Repeatable 分離レベルによるデッドロック
- Lock:Deadlock Chain イベント クラス
- Lock:Deadlock イベント クラス
- SET DEADLOCK_PRIORITY (Transact-SQL)
- Azure SQL Database と Fabric の SQL データベースのデッドロックを分析して防止する
- SQL Server Management Studio (SSMS) でデッドロック ファイルを開く、表示、印刷する