データベース操作・制御

デッドロック でっどろっく

ロックトランザクション排他制御同時実行制御タイムアウト
デッドロックについて教えて

簡単に言うとこんな感じ!

デッドロックは「AさんがBさんの席を待ち、BさんがAさんの席を待っている」状態だよ! 2人とも絶対に動けなくて永遠に待ち続けちゃう。DBで複数の処理が互いのデータを取り合って完全にフリーズしちゃう状態のことなんだ!


デッドロックとは

デッドロック(Deadlock)とは、2つ以上のトランザクションが互いに「相手が保持しているロックが解放されるのを待ち続ける」状態に陥り、どちらも処理を進められなくなる現象です。永久に待ち続けるため、外部から強制的に解消しない限り処理が完了しません。

具体例を挙げると、トランザクションAが「在庫テーブル」をロックして「注文テーブル」のロック待ち、同時にトランザクションBが「注文テーブル」をロックして「在庫テーブル」のロック待ちになった状態がデッドロックです。AはBを、BはAを待っているため、どちらも永遠に完了しません。

ほとんどのDBMSはデッドロックを自動検出し、一方のトランザクションを強制的にロールバック(犠牲者:victim)させることで解消します。アプリケーション側はエラーを受け取り、処理を再試行(リトライ)する設計が必要です。


デッドロックの発生メカニズム

デッドロック発生の仕組み トランザクションA トランザクションB 在庫テーブル 🔒 Aが保持 注文テーブル 🔒 Bが保持 Aが注文を待つ→ ←Bが在庫を待つ デッドロック! 互いに待ち続けてフリーズ DBMSがvictimを選びROLLBACKして解消

デッドロックの防止策

対策内容効果
ロック順序の統一複数テーブルを扱う場合、常に同じ順番でロックする(例:必ず「在庫→注文」の順)最も効果的な予防策
トランザクションの短縮トランザクション内の処理を短く保ちロック保持時間を最小化発生確率を下げる
適切な分離レベル必要以上に厳しい分離レベルを避けるロック競合を減らす
タイムアウト設定一定時間待ってもロックが取れない場合は自動ロールバック無限待ちを防ぐ
楽観ロック採用ロックを使わずバージョン番号で競合を検出する方式に変更ロック自体を減らす

歴史と背景

  • 1965年:E.W. ダイクストラが「哲学者の食事問題」でデッドロックの概念を示すモデルを提示
  • 1970年代:OSのプロセス管理でデッドロック問題が本格的に研究される(コフマン条件の定義)
  • 1980年代:商用RDBMSがデッドロック自動検出・解消機能を実装
  • 現在:DBMSはロック待ちグラフ(Wait-for Graph)を定期的にチェックしてサイクルを検出するアルゴリズムを標準実装。PostgreSQLはdeadlock_timeoutパラメータで検出間隔を制御できる

関連する規格・RFC

規格内容
コフマン条件相互排除・保持待機・非横取り・循環待機の4条件がすべて揃うとデッドロックが発生

関連用語