Two-phase commit and limits
2PC is the classic distributed transaction protocol: prepare, then commit. It blocks on coordinator failure and is fragile in practice.
Two-phase commit (2PC) is the classic protocol for atomic distributed transactions. A coordinator asks all participants "can you commit?" (prepare phase). If everyone says yes, it tells them all to commit (commit phase). If anyone says no or times out, everyone aborts.
The protocol
Phase 1 (prepare):
- Coordinator sends PREPARE to all participants.
- Each participant either votes YES (durably promises it can commit) or NO.
Phase 2 (commit):
- If all YES, coordinator sends COMMIT. Else ABORT.
- Participants apply and ack.
Why this is fragile
-
Coordinator failure between phase 1 and phase 2: participants are stuck holding locks, waiting for the commit decision. They cannot decide alone. This is the blocking problem.
-
Long-held locks: participants must hold transaction locks from prepare until commit. This kills throughput.
-
Coordinator is a SPOF: even with HA coordinators, the failure window during failover can leave participants in doubt.
-
Network partition: cuts off coordinator from participants mid-decision. Same blocking issue.
3PC (three-phase commit) tries to fix this with an extra "pre-commit" phase but has its own issues under network partition and is rarely used.
When 2PC works
- Inside a single database engine (e.g., Postgres internal 2PC for distributed transactions).
- Tightly coupled systems with shared infrastructure (XA transactions on the same datacenter).
- Low-throughput, high-correctness scenarios (financial settlement systems).
For most microservices: use sagas or outbox patterns.
Sagas: the modern alternative
Break the global transaction into a sequence of local transactions, each with a compensating action. If step 3 fails, run compensating actions for steps 1 and 2.
- Pro: no locking across services, no coordinator SPOF.
- Con: no isolation. Intermediate states are visible. Compensation must be designed carefully.
Example: book trip = (reserve flight, reserve hotel, charge card). Compensation: (release flight, release hotel, refund). Far more practical than 2PC for cross-service flows.
Learn more
- ArticleDesigning Data-Intensive Applications, Chapter 9Martin Kleppmann
- PaperSagas paperGarcia-Molina and Salem
- DocsXA distributed transactionsWikipedia