Two-Phase Commit (2PC)

Two-Phase Commit is a distributed transaction protocol that ensures atomicity across multiple database nodes. When a transaction spans multiple sites, 2PC coordinates all participants to either all commit or all abort — preventing partial commits.

The Two Phases

sequenceDiagram
    participant C as Coordinator
    participant P1 as Participant 1
    participant P2 as Participant 2

    Note over C,P2: Phase 1 - Prepare (Voting)
    C->>P1: PREPARE
    C->>P2: PREPARE
    P1-->>C: VOTE YES
    P2-->>C: VOTE YES

    Note over C,P2: Phase 2 - Commit (Decision)
    C->>P1: COMMIT
    C->>P2: COMMIT
    P1-->>C: ACK
    P2-->>C: ACK

Phase 1: Prepare (Voting)

  1. The coordinator sends a PREPARE message to all participants
  2. Each participant writes all transaction changes to its WAL and responds:
    • VOTE YES — Ready to commit (changes are durable in the log)
    • VOTE NO — Cannot commit (aborts locally)

Phase 2: Commit (Decision)

  1. If all participants voted YES → coordinator sends COMMIT to all
  2. If any participant voted NO → coordinator sends ABORT to all
  3. Participants execute the decision and acknowledge

The Blocking Problem

2PC’s main weakness: if the coordinator crashes after sending PREPARE but before sending the decision, participants are blocked — they hold locks, cannot commit or abort, and must wait for the coordinator to recover.

Three-Phase Commit (3PC)

Adds a pre-commit phase between voting and commit to reduce blocking. Participants that received pre-commit know the decision was commit, so they can proceed even if the coordinator fails. Rarely used in practice due to complexity and network partition issues.

2PC in Practice

  • PostgreSQL — Supports PREPARE TRANSACTION for distributed transactions
  • XA Protocol — Standard 2PC interface supported by most Database Management Systems (DBMS)
  • Microservices — Often replaced by the Saga pattern (compensating transactions) due to 2PC’s blocking nature and tight coupling