
過去問を解いていたら「デッドロック」でつまずきました……。

デッドロックは「なんだか難しそう」と思われがちだけど
実は条件と対策はとてもシンプルなんだよ。

シンプル……ですか?

そう。大事なのは「どの順番でロックを取っているか」だけなんだ。
第1章:デッドロックの基本理解
デッドロックの定義と直感的なイメージ
デッドロックとは
複数のトランザクションがお互いに資源を取り合い、待ち状態から抜け出せなくなる現象
を指します。
身近な例で言えば、狭い廊下で2人が向かい合って立ち止まり、どちらも道を譲らないために進めなくなる状況に似ています。
データベースの世界では、トランザクション同士が譲らない結果として処理が止まってしまうのです。
発生するための4つの条件
デッドロックは偶然発生するわけではなく、理論的に次の4条件が同時に成り立つときに起こります。
- 相互排他:ある資源は1つのトランザクションしか使えない
 - 保持と要求:資源を保持したまま別の資源を要求する
 - 非剥奪:保持している資源を強制的に奪えない
 - 循環待ち:トランザクション同士が輪を描くように待ち合う
 
この4条件が揃ったとき、デッドロックは必然的に発生します。
逆に言えば、どれか1つを崩せばデッドロックは防げます。
とは言え、データベーススペシャリスト試験ではここまで意識する必要は全くありません。
典型的なSQLでの発生例
例えば次のようなケースを考えてみましょう。
-- トランザクションA
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
-- トランザクションB
BEGIN;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;
ここでは、トランザクションAが先に id=1 をロックし、Bが先に id=2 をロックしています。
その後、Aは id=2 を、Bは id=1 を取りに行くため、互いに相手の解放を待ち続ける
――これがデッドロックです。
実際のDBMSでは、この状況を検出して一方のトランザクションを強制終了させる仕組みが備わっていることもあります。
第2章:デッドロックを防ぐための回避・対策
1,ロック取得順序を統一する
デッドロックが発生する典型パターン
「トランザクションAは資源1→資源2の順にロック」
「トランザクションBは資源2→資源1の順にロック」
という順序の違い
このような循環待ちを避けるには、「ロックを取得する順番」を統一することが効果的です。
例えば
- 必ずIDの小さい行からロックする
 - 必ずテーブルAをロックしてからテーブルBをロックする
 
といったルールを設ければ、デッドロックの発生確率は大幅に下がります。
2,トランザクションを短く保つ
トランザクションの実行時間が長いほど、他とのロック競合が発生しやすくなります。
特に、ユーザー入力待ちや複雑な処理をトランザクション内に含めるのは危険です。
デッドロックを回避するには、
更新処理に必要なSQLだけをまとめ、処理が終わったらすぐにCOMMIT/ROLLBACKする
ことが重要です。
第3章:午後Ⅰ過去問を用いた実例解説
平成31年度午後Ⅰ 問3
設問4の(3)に、デッドロックの問題があります。

左のデッドロックのケースを参考に、右の図を完成させる。という問題です。
左の図でデッドロックが発生しているということは、
片方はP3→P9、もう片方がP9→P3の順でロックを取得している
ということです。(第2章を参照)
つまり、次の図のように深さ優先で動いているのではなく

横向きになぞるように動いている。ということになります。

よって、右の図も同じようになぞった時、逆の順序で処理される番号を探せば良いのです。

続いての問題はこのようになっています。
”SQL4を、製品ごとレベルごと部品ごとに実行するのではなく、製品ごと部品ごとに集計した所要量をホスト変数HQTYに設定してから表4の手順⑥の前に実行するように、手順②~⑤を改良しました。”
この説明に加えて、複数回のSQL4をどのように実行するべきか、20字以内で述べよ。※SQL4は在庫テーブルの更新
平成31年春期 午後Ⅰ問3(4)
「製品ごとレベルごと部品ごとに実行するのではなく、製品ごと部品ごとに集計」
これは、横向きになぞっていた処理を深さ優先にしたということです。
※レベルごと。とは、同じ階層のものを調べていく。という調べ方を表しています。
では、それでデッドロックが完全に解消するかというと、そうではありません。

AX:P1→P2→P3・・・
AZ:P3→P7→P2・・・
P2とP3に着目すると、まさに逆順になっており、デッドロックの原因となります。
ではどうするのか。
SQL4の実行順序を揃えれば良いのです。
SQL4を部品の品番順に実行する。
これが解答です。
第4章:まとめ
デッドロックの解法はシンプル
デッドロックは「循環待ちがあるかどうか」を見抜くだけで判断できます。
さらに、対策も ロックの順序を揃える、トランザクションを短くする といった基本ルールで十分です。
試験問題は複雑に見えても、本質はこのシンプルな発想に集約されます。
午後Ⅰ対策が実務でも役立つ理由
午後問題は単なる学問的なパズルではなく、実際のシステム設計・運用で遭遇しうるトラブルをモデル化しています。
ロックの順序やトランザクションの設計方針を理解しておくことで、実務にも活かせるでしょう。
「試験のための勉強」が、そのまま 現場でのスキル に直結すると嬉しいですね!
  
  
  
  
