対象試験と出題頻度

2相コミットメント(2PC:Two-Phase Commit)は、応用情報技術者試験で出題されるテーマです。

分散データベースのトランザクション管理プロトコルとして、午前問題で「Prepareフェーズ」「Commitフェーズ」「コーディネータと参加者の役割」を問う形式が定番化しています。

詳細をクリックして確認
対象試験:
応用情報技術者
出題頻度:
★★☆☆☆
ランクC(応用)余裕があれば覚える

用語の定義

分散データベースを勉強していると、「2相コミットメントって結局何のためにあるの?」と引っかかりがちです。

2相コミットメント(Two-Phase Commit / 2PC)とは、一言で言うと

 複数のデータベースにまたがる更新処理を、全員一致でコミットするか全員一致でロールバックするかに揃えるプロトコル

のことです。

イメージとしては、結婚式の誓いの言葉です。

司会者(コーディネータ)が新郎新婦(参加者)に「誓いますか?」と1人ずつ確認します。両方が「はい(Yes)」と答えて初めて「夫婦として認めます」という宣言(コミット)が成立します。

片方でも「いいえ(No)」と答えれば、結婚は不成立(ロールバック)になります。

2相コミットメントも同じで、「全員の準備が整った確認」と「全員への確定指示」の2段階で更新の整合性を担保します。

📊 2相コミットメントの基本情報

項目 内容
英語名 Two-Phase Commit(2PC)
分類 分散トランザクションの同期プロトコル
登場人物 コーディネータ(調整役)/参加者(各サイト)
2つのフェーズ 第1相:Prepare(準備問合せ)/第2相:Commit or Rollback(確定指示)
保証する性質 分散環境におけるトランザクションの原子性(Atomicity)

解説

1台のデータベースで完結するトランザクションなら、コミットかロールバックかを単独で判断できます。

ところが、銀行の振込のように「東京サーバから10万円引く」「大阪サーバに10万円足す」といった更新が複数サイトに分散すると、片方だけ成功して片方が失敗する事態が起こり得ます。

これを放置すると残高が消えるか二重計上されるため、ACID特性のうち原子性(All or Nothing)が崩壊します。

この問題を解決するために設計された合意プロトコルが2相コミットメントです。

登場人物:コーディネータと参加者

役割 担当する処理
コーディネータ
(調停者)
全参加者にPrepare要求を送り、応答を集計して最終的なCommit/Rollbackを指示する司令塔。1つのトランザクションに1つだけ存在する。
参加者
(各サイトのDB)
自サイトの更新がコミット可能かを判定し、Yes/Noで応答する。Yesと答えた後はコーディネータの指示が来るまで結果を保留(待機)する。

図解:2フェーズの流れ

第1相:Prepareフェーズ(準備問合せ)

🎯

コーディネータ

①「コミット可能?」
➡️
⬅️
②「Yes / No」で応答
🗄️ 参加者A
🗄️ 参加者B

参加者はYesと答えた時点で更新内容をログに書き出し、いつでも確定できる状態で待機する

第2相:Commit/Rollbackフェーズ(確定指示)

参加者の応答 コーディネータの最終決定
全員がYes 全参加者へ Commit指示 を送信 → 各DBが更新を確定
1人でもNo
または無応答
全参加者へ Rollback指示 を送信 → 各DBが更新を破棄

通信シーケンスをコードで見る

抽象的な擬似コードで2PCの流れを書き下すと、コーディネータ側の処理は次のようになります。

// === 第1相:Prepare ===
votes = []
for participant in participants:
    response = participant.send("PREPARE")
    votes.append(response)

// === 第2相:判定とCommit/Rollback ===
if all(v == "YES" for v in votes):
    for participant in participants:
        participant.send("COMMIT")   // 全員一致 → 確定
else:
    for participant in participants:
        participant.send("ROLLBACK") // 1人でも反対 → 取消

2PCの弱点:ブロッキング問題

2PCには有名な弱点があります。

参加者がPrepareにYesと応答した後にコーディネータが故障すると、参加者は「コミットしていいのかロールバックすべきか」が判断できず、永続的に待機状態になります。これをブロッキング問題と呼びます。

これを解消するために、追加フェーズを設けた3相コミットメント(3PC)も提案されています。

では、この用語が試験でどのように出題されるか見ていきましょう。

💡 2相コミットメントの核心を3行で

・分散DBの原子性を守るための合意プロトコル
・第1相でPrepare(投票)、第2相でCommit/Rollback(確定)の2段階構成
・全員Yesでのみコミット、1人でもNoなら全員ロールバック


試験ではこう出る!

2相コミットメントは、APの午前問題で分散トランザクション分野の頻出キーワードとして出題されています。

📊 過去問での出題実績

試験回 出題内容 問われたポイント
AP H29春
午前 問28
2相コミットメントプロトコルの第1相における動作の説明として正しいものを選ぶ問題。 ・第1相=Prepare(コミット可否を問い合わせ/応答)
・「実際にコミットを行う」はひっかけ(第2相の動作)
AP H24春
午前 問31
分散データベースで2相コミットを採用する目的を選ぶ問題。 ・正解は「複数サイトの更新の原子性を保証する」
・性能向上やデータ圧縮はひっかけ
AP H22秋
午前 問33
第2相でコーディネータがCommit指示を出す条件を問う問題。 ・全参加者がYes応答した場合のみCommit
・「過半数」「自サイトのみYes」はひっかけ

📝 IPA試験での出題パターン

パターン1:「第1相/第2相の動作を選べ」
第1相は「Prepare問合せと応答収集」、第2相は「Commit/Rollback指示」です。第1相と第2相の動作を入れ替えた選択肢がひっかけとして頻出します。「第1相で実際にコミットする」と書かれていたら誤りです。

 

パターン2:「Commit確定の条件を問う」
「全参加者がYesと応答した場合のみコミット」が正解です。「過半数」「コーディネータの判断のみ」「最初のYesで確定」などはすべてひっかけです。

 

試験ではここまででOKです。3相コミットの詳細手順や具体的なログ書き出しタイミングまでは問われないので、深追いは不要です。


【確認テスト】理解度チェック

ここまでの内容を理解できたか、簡単なクイズで確認してみましょう。


Q. 分散データベースにおける2相コミットメント(2PC)の説明として、最も適切なものはどれでしょうか?

  • A. データベースを複数のサイトに複製しておき、参照性能を高めるとともに、1サイト障害時にも処理を継続できるようにする仕組み。
  • B. トランザクションを並行実行しても直列に実行した場合と同じ結果になることを保証するために、ロックを段階的に獲得・解放する制御方式。
  • C. 分散環境の全参加サイトに対しコーディネータがコミット可否を問い合わせ、全員がYesと応答した場合のみ全サイトでコミット、1サイトでもNoがあれば全サイトでロールバックさせるプロトコル。

正解と解説を見る

正解:C

解説:
選択肢Cは、コーディネータと参加者による2フェーズの合意手続きを正確に説明しており、2相コミットメントの定義そのものです。第1相のPrepare(投票)と第2相のCommit/Rollback(確定)という構造、および「全員一致でのみコミット」という原子性の保証条件が明示されています。

選択肢Aはレプリケーション(複製)の説明です。可用性や参照性能の向上を目的とする技術であり、複数サイトの更新の原子性を保証する仕組みとは目的が異なります。選択肢Bは2相ロック(2PL:Two-Phase Locking)の説明です。名前が似ていますが、2相ロックは並行実行時の直列化可能性を保証する同時実行制御の方式であり、分散コミットの合意プロトコルとは別物です。


よくある質問(FAQ)

Q. 2相コミットメント(2PC)と2相ロック(2PL)は何が違うのですか?

名前は似ていますが目的がまったく違います。2PCは「分散環境で複数サイトの更新を矛盾なく確定させる」ための合意プロトコルで、扱うのはコミットの意思決定です。一方2PLは「単一DBの中で並行実行されるトランザクションが直列化可能になる」よう、ロックを成長相と縮退相の2段階で管理する同時実行制御方式です。試験では両者を混同させる選択肢が出るため、「2PC=分散コミット」「2PL=ロック制御」と紐づけて覚えてください。

Q. 3相コミットメント(3PC)はどんな改良なのですか?

3PCは、Prepareと最終Commitの間に「Pre-Commit」という中間フェーズを挟む方式です。これにより、参加者は「全員がコミット意思を持っている」ことを最終Commit前に確認できるため、コーディネータが落ちても参加者同士でコミットを進められ、ブロッキング問題を緩和できます。ただしメッセージ往復が増えて性能が落ちるため、実装される場面は限定的です。応用情報の範囲では「2PCの弱点を補う方式」と知っていれば十分です。

Q. 実務ではどのような場面で2相コミットメントが使われますか?

代表例はXAトランザクション対応のミドルウェアで、複数のリソース(OracleとMySQL、DBとメッセージキューなど)を1つのトランザクションで束ねる場面です。Java EE/Jakarta EEのJTA、JBoss、WebLogicといったアプリケーションサーバが2PCをサポートしています。一方、近年のマイクロサービス構成では2PCの待機コストを嫌い、SagaパターンやEventual Consistencyで代替する設計が主流になりつつあります。

Q. コーディネータが故障したら絶対に復旧不可能なのですか?

完全に不可能ではありません。コーディネータが各フェーズの判断結果をトランザクションログに永続化していれば、再起動後にログを読み直して未完了トランザクションの後始末を行えます。これをリカバリ手続きと呼びます。ただし、コーディネータが復旧するまでの間、参加者は該当データのロックを保持し続けるため、他のトランザクションが待たされる影響は避けられません。これが「ブロッキング問題」が問題視される理由です。