SQL Serverで「急に処理が遅くなった」「特定の更新処理が止まっている」といった事象に遭遇した場合、内部でロック競合やブロッキングが発生している可能性があります。
本記事では、sys.dm_tran_locks を起点に、現在のロック状況を確認する基本クエリと、実運用で役立つ分析ポイントを体系的に整理します。障害対応や性能調査の初動で、即座に状況把握できることを目標に解説します。
SQL Serverのロックを可視化する基本クエリ
このセクションでは、SQL Server内部で「今、誰が・何を・どの粒度でロックしているのか」を確認するための最小構成のクエリを紹介します。
まずは全体像を把握し、怪しいセッションを見つけることが目的です。
sys.dm_tran_locksを使った基本クエリ
以下は、特定データベースに対して取得されているロックを一覧するシンプルなクエリです。
SELECT
request_session_id,
resource_type,
resource_description
FROM sys.dm_tran_locks
WHERE resource_database_id= DB_ID('AAA_TEST');
このクエリを実行すると、指定したデータベース上で現在ロックを保持しているセッションIDと、ロック対象の種別を確認できます。
✅ この時点で分かること
- どのセッションがロックを持っているか
- テーブル単位か、ページ・キー単位かといったロック粒度
- ロック数が異常に多いセッションの存在
まずは「ロックを大量に保持しているセッションがないか」を俯瞰することが重要です。
ロック情報から何が分かるのか?各カラムの意味と読み方
ロック情報は数が多く、そのままでは読みづらいことも少なくありません。
このセクションでは、実運用で特に重要となるカラムの意味と、読み取り方のポイントを整理します。
主要カラムの意味
- request_session_idロックを取得しているセッションIDです。
後続の調査では、このIDを軸に実行中SQLや接続元を深掘りします。
- resource_typeロック対象の種類を表します。
主な値としては以下があります。
OBJECT:テーブル全体PAGE:データページKEY:インデックスキーDATABASE:データベース全体
- resource_descriptionロックされているリソースの詳細情報です。
ページ番号やキー値など、内部的な識別情報が表示されます。
読み取り時の実践ポイント
✅ チェックすべき観点
OBJECTロックが多い場合→ テーブルロックに昇格している可能性があり、影響範囲が大きいKEYロックが大量に並んでいる場合→ 大量更新・インデックス設計の問題が疑われる- 同一
request_session_idが多数存在→ 1つのトランザクションが広範囲をロックしている兆候
数値や内部表現を細かく理解するより、「ロックの粒度と集中度」に注目すると分析しやすくなります。
実行中のSQLと紐づけて原因を探る
ロックの存在が分かっても、「何の処理が原因か」が分からなければ対処できません。
ここでは、ロック情報と実行中SQLを結び付ける方法を解説します。
ロック × 実行中リクエストの確認クエリ
SELECT
l.request_session_id,
r.command,
r.wait_type,
r.blocking_session_id,
t.textAS sql_text,
l.resource_type,
l.resource_description
FROM sys.dm_tran_locks l
JOIN sys.dm_exec_requests r
ON l.request_session_id= r.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE l.resource_database_id= DB_ID('AAA_TEST');
このクエリにより、以下を一度に確認できます。
✅ 把握できる情報
- 実行中のSQL文
- 現在のコマンド種別(SELECT / UPDATE など)
- 待機タイプ(ロック待ちかどうか)
- ブロッキングしている/されているセッション
特に sql_text を見ることで、「どのアプリケーション処理が原因か」を即座に特定できる点が重要です。
ブロッキング調査の際に見るべきポイント
パフォーマンス劣化の多くは、単なるロック取得ではなくブロッキングの連鎖によって発生します。
ここでは、調査時に必ず確認したいポイントを整理します。
注目すべきカラムと観点
- blocking_session_id値が入っている場合、そのセッションが待たされています。
まずは「誰が親ブロッカーか」を遡ることが重要です。
- wait_type
LCK_M_SやLCK_M_Xなどが表示されていれば、ロック待ちが原因です。 - wait_time待機時間が長いほど、ユーザー影響が大きいと判断できます。
- resource_typeテーブルロックか、行レベルロックかによって対策方針が変わります。
必要に応じて、sys.dm_exec_sessions を併用し、
ログインユーザー・接続元ホスト・アプリケーション名まで追跡すると、原因特定が一気に進みます。
【事例】トランザクションが開きっぱなしだったケース
実運用で非常によくあるのが、「意図せずトランザクションが長時間保持されていた」ケースです。
事象の概要
- アプリケーション側で
BEGIN TRANを実行 - 例外発生時に
COMMIT/ROLLBACKが実行されない - セッションが生き続け、ロックが解放されない
結果として、
- 更新系SQLがすべて待たされる
- SELECTすら遅延するといった深刻な影響が発生しました。
調査時の決め手
sys.dm_tran_locksで特定セッションが大量ロックsys.dm_exec_requestsでは処理が進んでいないsys.dm_exec_sessionsでアプリ名が特定できた
このようなケースでは、SQL Server側ではなくアプリケーションのトランザクション管理が根本原因であることが多いです。
まとめ:ロック確認クエリを運用調査に活かすには
SQL Serverのロック調査では、sys.dm_tran_locks を起点に、
実行中リクエスト・SQL文・セッション情報を段階的に結び付けていくことが重要です。
✅ 実運用でのポイント
- まずは「誰が大量にロックしているか」を把握
- 次に「何のSQLが原因か」を特定
- 最後に「アプリ or 設計 or 運用」のどこに問題があるかを切り分け
よく使うクエリはテンプレート化しておくと、障害対応時の初動が大幅に短縮されます。
本記事の内容をベースに、自社環境向けの調査手順を整備してみてください。

コメント