Instiq
第4章 · トランザクションと同時実行制御·v1.0.0·更新 2026/7/10·読了目安 約16分

変更要約: 初版

4.5分散トランザクションと2相コミット

この節の要点

複数のデータベースサイトにまたがるトランザクションの原子性を保証する2相コミット(2PC)準備(コミット要求)フェーズコミットフェーズ、その弱点を補う3相コミット(3PC)、そして2PCのブロッキング問題を学び、分散環境で一貫性をどう確保すべきかを判断する力を養います。

在庫データベースと決済データベースが別サーバに分かれているシステムを設計するアーキテクトにとって、「複数サイトにまたがる更新をどう原子的にコミットするか」は、分散システム特有の難問です。単一データベースのCOMMITと異なり、ネットワークの遅延や一部サイトの障害を考慮しなければなりません。この節では、分散トランザクションの一貫性をどう確保すべきか、そして2相コミットが抱える弱点にどう向き合うかを判断する視点を養います。

4.5.12相コミット(2PC)の2つのフェーズ

  • 2相コミット(2PC:Two-Phase Commit)=1つのトランザクションが複数のデータベースサイト(参加者)にまたがる場合に、全サイトが揃って原子的にCOMMITまたはROLLBACKすることを保証するプロトコル。コーディネータ(調整者)が各参加者(Participant)とやり取りし、2つのフェーズで進める。
  • 第1フェーズ(準備フェーズ/コミット要求フェーズ)=コーディネータが全参加者に「コミットできるか」を問い合わせる。各参加者は自身の更新内容をログに書き込んだ上で「準備完了(YES)」または「拒否(NO)」を応答する。第2フェーズ(コミットフェーズ)=全参加者からYESが揃えば、コーディネータは全参加者にCOMMIT命令を送り確定させる。1つでもNOがあれば、または応答がタイムアウトすれば、コーディネータは全参加者にROLLBACK命令を送り取り消す。

4.5.22PCのブロッキング問題と3相コミット

  • ブロッキング問題=第1フェーズで全参加者が「準備完了(YES)」を応答した直後にコーディネータ自身が障害でダウンすると、各参加者は「COMMITすべきかROLLBACKすべきか」の指示を受け取れず、コーディネータが復旧するまで保持しているロックを解放できずに待ち続ける(ブロックする)という2PC最大の弱点。この間、他のトランザクションもそのロックの解放待ちで連鎖的に影響を受け得る。
  • 3相コミット(3PC:Three-Phase Commit)=2PCの準備フェーズとコミットフェーズの間に「プリコミットフェーズ」を挟むことで、コーディネータ障害時にも参加者同士のタイムアウトや状態確認によってブロッキングを回避しやすくするプロトコル。ただし、メッセージ往復が増えレイテンシが増加するうえ、ネットワーク分断(CAP定理が指す分断耐性の議論)が絡む状況では完全にブロッキングを排除できるわけではないため、低遅延を重視する多くの実務システムでは今なお2PCが広く使われる
試験ポイント

「2PC第1フェーズ=準備完了/拒否の問合せ」「2PC第2フェーズ=全員YESならCOMMIT命令・1人でもNOやタイムアウトならROLLBACK命令」「2PCの弱点=コーディネータ障害時のブロッキング問題」「3PC=プリコミットフェーズ追加でブロッキング緩和だがレイテンシ増」が最頻出です。3PCが「ブロッキングを完全に排除する」わけではない点に注意。

あるECシステムのアーキテクトが、注文確定時に在庫データベース(サイトA)決済データベース(サイトB)という別々のサーバへ同時に更新をかける分散トランザクションを設計しているとします。まず、両サイトの更新を原子的に確定させるため2相コミット(2PC)を採用します——コーディネータ(例えばアプリケーションサーバ)が両サイトへ「準備できるか」を問い合わせる第1フェーズを実行し、在庫減算・決済確定の両方が準備完了(YES)と応答すればCOMMIT命令を、どちらか一方でも準備できない(NO)と応答すればROLLBACK命令を両サイトへ送る第2フェーズで確定させます。ここでアーキテクトが検討すべきなのが、両サイトが準備完了を応答した直後にコーディネータ自体がクラッシュした場合のリスクです——この場合、在庫データベースも決済データベースも「最終的にCOMMITすべきかROLLBACKすべきか」の指示を受け取れず、それぞれが保持しているロックを解放できずに待ち続けるブロッキング状態に陥り、それが原因で在庫・決済に関連する他の注文処理まで連鎖的に待たされる可能性があります。ここでアーキテクトが「3相コミット(3PC)に切り替えればブロッキング問題が完全に解消するので無条件に採用すべきだ」と判断するのは誤りです——3PCはプリコミットフェーズの追加により参加者同士の状態確認でブロッキングを緩和しやすくするものであり、メッセージ往復の増加によるレイテンシ増大というコストを伴い、かつネットワーク分断が絡む状況では完全にブロッキングを排除できるわけではないため、低レイテンシが最重要要件のECシステムでは、コーディネータの高可用性構成(冗長化・自動フェイルオーバー)によってブロッキングの発生確率自体を下げる対策と2PCを組み合わせる方が実務上妥当な判断になり得ます。

フェーズ/方式内容
2PC第1フェーズ(準備)コーディネータが全参加者に準備可否を問合せ・各参加者はログ書込み後YES/NOを応答
2PC第2フェーズ(コミット)全員YESならCOMMIT命令・1人でもNO/タイムアウトならROLLBACK命令
ブロッキング問題コーディネータ障害時に参加者が指示を受け取れずロック保持のまま待機
3PCプリコミットフェーズ追加でブロッキング緩和・ただしレイテンシ増、完全排除ではない
注意

ひっかけ: 「3相コミット(3PC)を採用すればブロッキング問題は完全に解消される」は誤りです——3PCはブロッキングを緩和しやすくするがレイテンシ増大というコストを伴い、ネットワーク分断が絡む状況では完全には排除できません。また「2PCの第1フェーズでYESと応答した参加者は、その後コーディネータの指示を待たず独自にCOMMITしてよい」も誤り=必ず第2フェーズのコーディネータからの命令を待つ必要があり、独自判断でのCOMMITは分散環境全体の原子性を崩します。

2相コミットの準備/コミット相の図。
複数DBを一貫させる

4.5.3この節のまとめ

  • 2相コミット(2PC)は準備フェーズ(YES/NO収集)とコミットフェーズ(全員YESならCOMMIT・1人でもNO/タイムアウトならROLLBACK)で分散トランザクションの原子性を保証する
  • 2PC最大の弱点はブロッキング問題(コーディネータ障害時に参加者がロックを保持したまま待機し続ける)
  • 3相コミット(3PC)はブロッキングを緩和するがレイテンシ増を伴い完全排除ではない——要件に応じてコーディネータ高可用化等と組み合わせる

進捗の記録にはログインが必要です。

理解度チェック

(軽い確認用)

Q1. 在庫データベースと決済データベースにまたがる分散トランザクションで、両サイトが2相コミット(2PC)の第1フェーズで準備完了(YES)を応答した直後に、コーディネータ自体が障害でダウンした。この時点で発生し得る問題として最も適切なものはどれか。

Q2. 低レイテンシが最重要要件のECシステムのアーキテクトが、2PCのブロッキング問題への対処として3相コミット(3PC)への切り替えを検討している。この判断について最も適切な評価はどれか。

Q3. 2相コミット(2PC)の第1フェーズで、ある参加者が「準備完了(YES)」を応答した。この参加者が取るべき行動として最も適切なものはどれか。

理解度を確認第4章「トランザクションと同時実行制御」の問題を解く

学習の記録を残しませんか

参考書はすべて無料で読めます。無料登録すると、問題集での演習・既読と進捗の記録・間違えた問題の復習・ハイライトが使えます。