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)
- The coordinator sends a
PREPAREmessage to all participants - 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)
- If all participants voted YES → coordinator sends
COMMITto all - If any participant voted NO → coordinator sends
ABORTto all - 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 TRANSACTIONfor 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