Two-Phase Commit
A coordinator asks every participant to prepare, then tells them all to commit or abort. It gives atomic distributed transactions, but blocks if the coordinator fails at the wrong moment.
Two-phase commit (2PC) makes a transaction that spans several databases or services atomic: either every participant commits, or none does.
The protocol
Phase 1: prepare (voting). The coordinator sends prepare to every participant. Each one does the work, makes it durable without making it visible, holds its locks, and votes yes (“I can definitely commit”) or no.
Phase 2: commit or abort. If every vote was yes, the coordinator writes its decision to its log and sends commit. If anyone voted no or timed out, it sends abort. Participants act and acknowledge.
The crucial promise is the yes vote: once a participant votes yes, it has given up the right to abort on its own. It must wait for the coordinator’s decision.
The weakness: blocking
If the coordinator crashes after participants voted yes but before they hear the decision, they’re stuck. They can’t commit (someone might have voted no) and can’t abort (the coordinator might have decided commit). They hold their locks until the coordinator recovers. That’s why 2PC is called a blocking protocol, and why it isn’t a full answer to The Consensus Problem: one failure can halt progress.
Fixes exist: three-phase commit (which assumes bounded delays), or making the coordinator itself fault-tolerant by replicating its log with consensus (Raft). That’s roughly what modern distributed databases do.
An example
Transferring money between accounts held in two databases: debit one, credit the other. Both prepare (funds reserved, credit staged), the coordinator records “commit”, both apply. If the second bank’s database says no, the reservation is released. No money appears or vanishes.
Alternatives in microservices
2PC couples services tightly and holds locks across the network, so many microservice architectures avoid it:
- Sagas: a sequence of local transactions, each with a compensating action to undo it if a later step fails.
- Transactional outbox plus idempotent consumers (Message Delivery Semantics).
Both trade immediate atomicity for availability and looser coupling, the same trade-off as in the CAP Theorem.
In practice
I’ve never hand-rolled 2PC, and I hope I never will. But knowing how it works explains why “just update both services in one request” is a much harder problem than it sounds, and why workflow platforms model long-running processes as steps with compensation rather than one big transaction.
- #distributed-systems
- #transactions
- #consensus
- #databases
↩ Linked from (1)
- The Consensus ProblemGrowing
…e votes and the coordinator announces the result", fail when the coordinator dies at the wrong moment. That's Two-Phase Commit's weakness.
↪ Links to (4)
Related by topic
- Evergreen
Architecture Decision Records
Career - Growingmetaphor
Balance Is a Control Loop
Calisthenics Lab - Seed
Deadlock and Starvation
Distributed systems - Evergreen
Fallacies of Distributed Computing
Distributed systems