デッドロック でっどろっく
ロックトランザクション排他制御同時実行制御タイムアウト
デッドロックについて教えて
簡単に言うとこんな感じ!
デッドロックは「AさんがBさんの席を待ち、BさんがAさんの席を待っている」状態だよ! 2人とも絶対に動けなくて永遠に待ち続けちゃう。DBで複数の処理が互いのデータを取り合って完全にフリーズしちゃう状態のことなんだ!
デッドロックとは
デッドロック(Deadlock)とは、2つ以上のトランザクションが互いに「相手が保持しているロックが解放されるのを待ち続ける」状態に陥り、どちらも処理を進められなくなる現象です。永久に待ち続けるため、外部から強制的に解消しない限り処理が完了しません。
具体例を挙げると、トランザクションAが「在庫テーブル」をロックして「注文テーブル」のロック待ち、同時にトランザクションBが「注文テーブル」をロックして「在庫テーブル」のロック待ちになった状態がデッドロックです。AはBを、BはAを待っているため、どちらも永遠に完了しません。
ほとんどのDBMSはデッドロックを自動検出し、一方のトランザクションを強制的にロールバック(犠牲者:victim)させることで解消します。アプリケーション側はエラーを受け取り、処理を再試行(リトライ)する設計が必要です。
デッドロックの発生メカニズム
デッドロックの防止策
| 対策 | 内容 | 効果 |
|---|---|---|
| ロック順序の統一 | 複数テーブルを扱う場合、常に同じ順番でロックする(例:必ず「在庫→注文」の順) | 最も効果的な予防策 |
| トランザクションの短縮 | トランザクション内の処理を短く保ちロック保持時間を最小化 | 発生確率を下げる |
| 適切な分離レベル | 必要以上に厳しい分離レベルを避ける | ロック競合を減らす |
| タイムアウト設定 | 一定時間待ってもロックが取れない場合は自動ロールバック | 無限待ちを防ぐ |
| 楽観ロック採用 | ロックを使わずバージョン番号で競合を検出する方式に変更 | ロック自体を減らす |
歴史と背景
- 1965年:E.W. ダイクストラが「哲学者の食事問題」でデッドロックの概念を示すモデルを提示
- 1970年代:OSのプロセス管理でデッドロック問題が本格的に研究される(コフマン条件の定義)
- 1980年代:商用RDBMSがデッドロック自動検出・解消機能を実装
- 現在:DBMSはロック待ちグラフ(Wait-for Graph)を定期的にチェックしてサイクルを検出するアルゴリズムを標準実装。PostgreSQLは
deadlock_timeoutパラメータで検出間隔を制御できる
関連する規格・RFC
| 規格 | 内容 |
|---|---|
| コフマン条件 | 相互排除・保持待機・非横取り・循環待機の4条件がすべて揃うとデッドロックが発生 |
関連用語
- ロック(排他制御) — データの同時更新を防ぐためにアクセスを制限する仕組み
- 楽観ロック・悲観ロック — 同時更新を制御する2つのアプローチ
- トランザクション — 一連のDB操作をひとまとめに扱う仕組み
- 分離レベル — 同時実行トランザクション間の干渉をどこまで許容するかの設定
- MVCC — ロックを最小化しながら整合性を保つ並行処理技術
- コミット・ロールバック — トランザクションを確定または取り消す操作
- コネクションプール — DB接続を再利用して効率化する仕組み