最終更新日:2026年9月3日
fe fe-technology database
まず結論
デッドロックとは、複数のトランザクションが、互いに相手のロックしている資源の解放を待ち続け、どの処理も先へ進めなくなる状態です。
基本情報技術者試験では、次の切り分けが重要です。
一方だけが待つ
→ 通常のロック待ち
AがBを待つ
かつ
BがAを待つ
→ デッドロック
覚え方は、「お互い待ちで、誰も進めない」です。
特にロック取得順序を問う問題では、次の判断が強力です。
同じ順序でロック
→ 循環待ちになりにくい
逆の順序でロック
→ お互い待ちになりやすい
直感的な説明
2人が、それぞれ別の道具を持っている場面を考えます。
トランザクションA
資源Xをロックしている
資源Yが空くのを待っている
トランザクションB
資源Yをロックしている
資源Xが空くのを待っている
AはBの持つ資源Yを待ち、BはAの持つ資源Xを待っています。
A ──Yを待つ──> B
A <──Xを待つ── B
しかし、どちらも自分の資源を保持したままなので、処理が止まったままになります。これがデッドロックです。
一方で、次のように片方だけが待つ場合は、通常のロック待ちです。
Aが資源Xをロック
↓
Bは資源Xを待つ
↓
Aが処理を終了してロック解除
↓
Bが処理を開始
この場合は、いずれBが進めます。
「待っている」だけではデッドロックではありません。待ち関係が輪になっているかを見ることが重要です。
定義・仕組み
ロックと排他制御
データベースでは、複数のトランザクションが同じデータを同時に更新すると、不整合が起きることがあります。
そのため、あるトランザクションが使用中のデータをロックし、他のトランザクションからのアクセスを制限します。これが排他制御です。
ロックそのものは異常ではありません。問題は、複数のロック待ちが循環することです。
共有ロックと専有ロックの両立性については、共有ロックと専有ロックとは?ロックの両立性の見分け方で詳しく整理しています。
read と update をロックに置き換える
FEの問題では、問題文で次のように指定されることがあります。
read
→ 共有ロック
update
→ 専有ロック
共有ロック同士は共存できますが、専有ロックが関わると同じ資源を同時には利用できません。
| 既存のロック | 新たに共有ロック | 新たに専有ロック |
|---|---|---|
| 共有ロック | ○ | × |
| 専有ロック | × | × |
試験では、まず次の一言で十分です。
共有+共有だけ○。それ以外は待つ。
デッドロックが起きる流れ
例えば、次のような順番で処理したとします。
1. Aが資源Xを専有ロック
2. Bが資源Yを専有ロック
3. Aが資源Yを要求 → Bが持っているので待つ
4. Bが資源Xを要求 → Aが持っているので待つ
すると、
A:Xを持ったままY待ち
B:Yを持ったままX待ち
となります。
A → B待ち
B → A待ち
このように待ち関係が輪になることを、循環待ちと呼びます。
デッドロックの成立条件
一般に、デッドロックは次の条件が重なったときに発生します。
| 条件 | 意味 |
|---|---|
| 相互排他 | 一つの資源を同時に複数の処理が使えない |
| 保持して待つ | 資源を保持したまま、別の資源を待つ |
| 横取りできない | 他の処理が強制的に資源を奪えない |
| 循環待ち | 複数の処理が輪になって互いを待つ |
FE試験では、四つすべてを毎回確認するよりも、まず循環待ちができるかを見ると判断しやすくなります。
2相ロッキングとは
2相ロッキングは、ロック操作を大きく次の2段階に分ける考え方です。
第1相:ロックを獲得していく
↓
第2相:ロックを解放していく
重要なのは、いったんロックを解放する段階に入った後で、新しいロックを獲得しないことです。
実際のDBMSや2相ロッキングの派生方式では、ロックを保持する期間に違いがあります。FEのトレース問題では、問題文で示されたロック取得・解放の前提を優先してください。
2相ロッキングの問題で最初に見るもの
例えば、トランザクションAが次の順番で処理するとします。
read W
update X
update Y
update Z
問題文から、
read W → Wの共有ロック
update X → Xの専有ロック
update Y → Yの専有ロック
update Z → Zの専有ロック
と置き換えます。
このとき、デッドロック判定で特に注目したいのは専有ロックの順番です。
A:X → Y → Z
もう一つのトランザクションBも、
B:X → Y → Z
と同じ順番で資源をロックするなら、一方が先にXを取得した時点で、もう一方はXで待ちます。
待たされた側は、まだYやZを持っていません。
そのため、
AがBを待つ
かつ
BがAを待つ
という輪を作りにくくなります。
反対に、
A:X → Y → Z
B:Y → Z → X
のように順番が異なるとします。
Bが先にYを取得し、Aが先にXを取得すると、
A:Xを保持したままYを要求
→ YはBが保持
→ AはB待ち
B:Yを保持したままXを要求
→ XはAが保持
→ BはA待ち
となります。
A:Xを持ってY待ち
B:Yを持ってX待ち
A → B
↑ ↓
└───┘
これがデッドロックです。
科目Aでどう出る?
科目Aでは、デッドロックの説明を選ぶ問題だけでなく、二つのトランザクションの命令順序から、デッドロックが発生しない処理順序を選ぶ問題もあります。
選択肢を切る判断表
| 説明 | 判断 |
|---|---|
| 一方のトランザクションだけがロック解除を待つ | 通常のロック待ち |
| 使用中の資源へ他からアクセスできなくする | 排他制御 |
| 複数のトランザクションが互いの資源を待つ | デッドロック |
| 二つの処理が同じ順番で複数資源をロックする | デッドロックを避けやすい |
| 二つの処理が逆順で複数資源をロックする | 循環待ちに注意 |
特に重要なのは、待っているだけではデッドロックとは限らないことです。
一方向の待ち
→ 先の処理が終われば進める
循環した待ち
→ お互いが相手の終了を待つので進めない
トレース問題はこの順番で解く
複雑な図を最初から全部追う必要はありません。
1. read / update を共有・専有ロックへ置き換える
2. 共有+共有だけは同時に使えると確認する
3. 各トランザクションの専有ロック取得順を並べる
4. 「誰が何を持って、何を待つか」を書く
5. A→B→A のような循環ができるか確認する
例えば、
A:X → Y → Z
B:X → Y → Z
なら、同じ順番です。
一方、
A:X → Y
B:Y → X
なら、
A:Xを持ってY待ち
B:Yを持ってX待ち
になる可能性があります。
試験中は「ロック取得順序がそろっているか」を最初に見ると、かなり速く選択肢を切れます。
どんな場面で使う?
デッドロックは、複数の処理が同時にデータを更新する場面で問題になります。
例えば、次のような処理です。
- 銀行口座間の振込
- 在庫数と注文情報の同時更新
- 複数テーブルにまたがる更新
- 予約処理と決済処理
- 生産管理システムでの複数設備データ更新
対策1:ロックする順番を統一する
全トランザクションが、必ず同じ順番で資源をロックするようにします。
A:X → Y → Z
B:X → Y → Z
順番を統一すると、ある処理が途中の資源を保持したまま、別の処理が逆側の資源を保持する状況を避けやすくなります。
PostgreSQLの公式ドキュメントでも、複数のオブジェクトをロックするときは一貫した順序で取得することが、デッドロックを避ける基本策として説明されています。
対策2:ロック時間を短くする
トランザクションを必要以上に長くしないようにします。
- 不要な処理をトランザクションの外へ出す
- コミットやロールバックを適切に行う
- ユーザー入力を待ちながらロックし続けない
対策3:検出後に一方を取り消す
DBMSによっては、デッドロックを検出すると、一方のトランザクションを中止・ロールバックして待ち状態を解消します。
これは、すべての処理をそのまま成功させるのではなく、一つを取り消して循環を崩す考え方です。
よくある誤解・混同
ロック待ちはすべてデッドロック
違います。
Aが処理中
↓
BがAを待つ
↓
Aが終了
↓
Bが進む
これは通常のロック待ちです。
デッドロックでは、
AがBを待つ
BがAを待つ
という循環があります。
「待ち」が発生した選択肢は不正解
これも違います。
FEのロック順序問題では、途中でロック待ちが発生しても、先行するトランザクションが終了すれば後続が進めるなら問題ありません。
待つ
≠ デッドロック
循環待ちになったときだけデッドロックです。
後から処理を続けられそうならデッドロックではない
ロックを保持したまま待つ前提では注意が必要です。
例えば、
A:Xを保持 → Y待ち
B:Yを保持 → 次にXが必要
なら、Bが「そのうち処理を終える」と考えてはいけません。
BはXを取得できないため止まり、AもYを取得できないため止まります。
今持っているロックを保持したまま、次のロックを取れるかを一手ずつ確認します。
排他制御はデッドロックそのもの
排他制御は、データの不整合を防ぐための正常な仕組みです。
排他制御
→ 必要な仕組み
デッドロック
→ 排他制御中に起こり得る問題
2相コミットと2相ロッキングは同じ
名前は似ていますが、目的が異なります。
| 用語 | 目的 |
|---|---|
| 2相コミット | 分散した複数システムでコミットをそろえる |
| 2相ロッキング | ロックの獲得段階と解放段階を分ける |
| デッドロック | 互いの資源を待って処理が進まない状態 |
参考になる一次情報
基本情報技術者試験の最新シラバスでは、データベースの同時実行制御(排他制御)について、ロック方式の基本的な仕組みを理解することが求められており、用語例として専有ロック、共有ロック、ロック粒度、デッドロックなどが挙げられています。
PostgreSQLの公式説明では、二つのトランザクションがそれぞれ別の資源を保持し、相手が保持する資源を要求すると両方とも進めなくなる例が示されています。また、複数資源のロック取得順序を統一することがデッドロック回避の基本策として説明されています。
確認問題(基本情報技術者試験対策)
トランザクションPとQが、資源XとYを更新するとします。
P:X → Y の順にロック
Q:Y → X の順にロック
PがXを保持し、QがYを保持した後、PがY、QがXを要求した。この状態として最も適切なものはどれか。
- ア. 共有ロック同士なので、そのまま両方とも進める
- イ. 一方向のロック待ちなので、どちらかが自然に終了する
- ウ. 互いに相手の資源を待つデッドロックである
- エ. 2相コミットによって自動的に解決する
▶ クリックして答えと解説を見る(ここを開く)
正解:ウ
P:Xを保持 → Y待ち
Q:Yを保持 → X待ち
PはQを待ち、QはPを待っています。
待ち関係が循環しているため、デッドロックです。
まとめ(試験直前用)
- デッドロックは「AがBを待ち、BもAを待つ」循環待ち
- 一方だけが待つなら、通常のロック待ち
- readは共有、updateは専有と指定されたら、そのままロックへ置き換える
- 共有+共有だけは共存できる
- トレース問題では、まず専有ロックを取る順番を見る
- 同じ順番で資源を取れば循環待ちを避けやすい
- 逆順で資源を取ると「Xを持ってY待ち / Yを持ってX待ち」に注意する