How Two-Phase Commit Works
AdvancedTwo-phase commit (2PC) is a protocol for making a transaction atomic across multiple databases or services — either all commit or all abort. A coordinator runs two rounds: first it asks every participant to prepare (can you commit?), and only if all say yes does it tell them all to commit. It guarantees atomicity, but it is blocking: if the coordinator crashes at the wrong moment, participants can be stuck holding locks. This fragility is why microservices usually prefer sagas.
Think of scheduling a meeting everyone must attend
To lock in a meeting, you (the coordinator) first ask each person "can you make 3pm?" and they tentatively hold the slot (prepare). Only when everyone confirms do you send the final invite (commit). If even one says no, you cancel for all. The catch: if you disappear after collecting the yeses but before sending the invite, everyone is stuck holding 3pm open, unsure whether the meeting is on — the blocking problem of 2PC.
Step by Step
Key Concepts
Coordinator and Participants
The coordinator drives the protocol; participants are the databases or services being committed. All communication and the final decision flow through the coordinator.
Prepare Phase
Phase one, where each participant does the work, durably logs it, locks the data, and votes yes/no — committing to be able to commit, without actually committing yet.
Blocking Problem
If the coordinator fails after the prepare phase, prepared participants are stuck holding locks, unable to safely commit or abort on their own — reducing availability.
2PC vs Saga
Both aim for consistency across services. 2PC uses distributed locks and a synchronous commit (strong but blocking). A saga uses local transactions plus compensations (available and eventually consistent) — the microservices favourite.
Key Facts
- 2PC guarantees atomicity but at the cost of availability: it holds locks across services and blocks if the coordinator fails at the wrong time.
- Three-phase commit adds a phase to reduce blocking, but it is more complex and still not fully partition-tolerant, so it is rarely used in practice.
- Microservices generally avoid 2PC in favour of sagas, trading immediate atomicity for availability and eventual consistency.
Real-World Applications
XA transactions across databases
Enterprise systems sometimes use 2PC (via the XA standard) to commit atomically across, say, a database and a message broker — accepting the locking and blocking risk for the strong guarantee.
Why a checkout uses a saga instead
A modern checkout spanning inventory, payment, and shipping services avoids 2PC (which would lock all three) and uses a saga with compensating transactions, keeping the system available even if one service is slow.
Frequently Asked Questions
What are the two phases of two-phase commit?
Phase one is prepare: the coordinator asks every participant if it can commit, and each does its work, logs it durably, locks the data, and votes yes or no without committing. Phase two is commit (or abort): if all voted yes, the coordinator tells everyone to commit; if any voted no, it tells everyone to abort. This ensures all participants reach the same outcome atomically.
What is the blocking problem in 2PC?
It occurs when the coordinator crashes after participants have prepared (voted yes) but before it sends the final commit or abort decision. The prepared participants have promised to commit and cannot safely decide on their own, so they remain stuck holding locks and waiting for the coordinator to recover. This reduces availability and is 2PC main weakness.
Why do microservices prefer sagas over two-phase commit?
Because 2PC holds locks across multiple services and blocks if the coordinator fails, which hurts availability and scales poorly. Sagas instead use a sequence of local transactions with compensating actions to undo on failure, avoiding distributed locks. This favours availability and eventual consistency, which fits the independent, loosely-coupled nature of microservices far better.
What is three-phase commit?
Three-phase commit (3PC) adds an extra phase between prepare and commit to reduce the blocking problem, allowing participants to make progress in more coordinator-failure scenarios. However, it is more complex, adds latency, and is still not fully safe under network partitions, so it is rarely used in practice — most systems choose sagas or accept 2PC limitations.