頻出高 ⏱ 7分★★★★★

デッドロック

循環待ち・待機グラフ・予防策を完全理解

2 つ以上のトランザクションが互いに相手のロック解放を待ち合う状態。どちらも先に進めず永遠に待ち続ける膠着状態(循環待ち)。

T1 と T2 が互いのリソースを待ち合う
時刻トランザクション T1トランザクション T2
T1テーブル A をロック(X)
T2テーブル B をロック(X)
T3テーブル B を要求 → T2 が保持中のため待機
T4テーブル A を要求 → T1 が保持中のため待機
T5🔴 デッドロック:両者が永遠に待ち合う

DBMS がデッドロックを検出するために使うグラフ。「A が B を待っている」という有向辺を引き、サイクル(循環)が検出されるとデッドロックと判断する。

待機グラフの例
T1
T2
T3
T1 ← サイクル!

T1→T2→T3→T1 の循環 = デッドロック確定

① DBMS が定期的に待機グラフを構築
② サイクル(循環依存)を検出
③ 犠牲者(Victim)を選択してロールバック(コスト・優先度・更新量で選択)
④ 残りのトランザクションがロックを取得して続行
犠牲者のトランザクションはエラーで終了する。アプリケーション側でデッドロックエラーを検知してリトライする実装が必要。
予防策の比較
予防策方法効果
ロック順序の固定全トランザクションが同じ順序でロックを取得✅ 最も確実・循環を防ぐ
一括ロック必要なロックを全て最初に取得✅ 循環なし・並行性低下
ロックタイムアウト一定時間後に自動 ROLLBACK△ 解決するが発生は防がない
楽観的ロックロックを使わずコミット時に確認✅ 競合が少ない場面で有効
トランザクション短縮処理を短くしてロック保持時間を減らす✅ 競合窓口を縮小
-- NG:T1 は A→B、T2 は B→A の順でロックするとデッドロック
-- T1: LOCK A; LOCK B;
-- T2: LOCK B; LOCK A;  ← 逆順!

-- OK:常に「小さい ID のテーブルから」という順序ルールを徹底
-- T1: LOCK A; LOCK B;
-- T2: LOCK A; LOCK B;  ← 同じ順序!
ロック順序の統一は設計レベルで決めておく。複数テーブルを更新するストアドプロシージャでも順序を揃える。

📝 理解度チェック

デッドロックが発生する根本的な原因はどれか?
DBMS がデッドロックを検出する主な方法はどれか?
デッドロックの最も確実な予防策はどれか?

読了ボタンを押すとトップページの進捗に反映されます