What are 2PC and Saga patterns for distributed transactions?
Distributed transactions arise when a single business operation must update data across multiple services or database nodes atomically. Two-Phase Commit (2PC) and the Saga pattern are the two dominant approaches, with fundamentally different consistency guarantees and failure models.
**Two-Phase Commit (2PC)** uses a coordinator to achieve distributed atomicity. Phase 1 (Prepare): the coordinator sends a PREPARE to all participants, which each execute the transaction locally, write to a write-ahead log, and vote YES or NO. Phase 2 (Commit/Abort): if all vote YES, the coordinator sends COMMIT; if any vote NO, it sends ABORT. All participants apply or roll back accordingly.
The critical flaw: 2PC is a blocking protocol. If the coordinator crashes after sending PREPARE but before sending COMMIT, participants are in an uncertain state—they've locked resources and cannot proceed without the coordinator. This is the 'in-doubt' window, and it can block indefinitely. It also requires all participants to be available simultaneously, making it impractical across microservices with independent availability SLAs. 2PC is appropriate for coordinating nodes within a single database system (e.g., XA transactions across two PostgreSQL instances in the same data center) but is rarely used across services.
**Saga pattern** decomposes a long-running transaction into a sequence of local transactions, each publishing an event or message that triggers the next step. Consistency is achieved through compensating transactions—each step has an inverse that undoes its effect if a later step fails.
There are two coordination styles. **Choreography**: each service listens for events and decides what to do next—decentralized, lower coupling, but harder to trace the overall workflow. **Orchestration**: a central saga orchestrator (or state machine) explicitly calls each service in sequence and handles failures—easier to observe and debug, but introduces a coordination point.
Sagas provide eventual consistency, not atomicity. Compensations are not rollbacks—they issue new transactions that semantically undo prior work (e.g., issuing a refund vs. reversing a payment). This means the system can be in an inconsistent intermediate state during execution, which is acceptable for many business workflows but requires careful design of idempotency and compensation logic.
Use 2PC when you need strong ACID atomicity across a small number of co-located resources and can tolerate the blocking risk. Use Saga when you need to coordinate across microservices with independent deployments, high availability requirements, or long-running workflows where blocking is unacceptable.
| Aspect | 2PC | Saga |
|---|---|---|
| Consistency model | Strong (ACID atomicity) | Eventual (compensatable) |
| Blocking on failure | Yes — blocks in-doubt until coordinator recovers | No — proceeds via compensations |
| Cross-service support | Poor (requires XA support) | Excellent (message/event based) |
| Coordinator dependency | Single coordinator SPOF | Orchestrator or decentralized choreography |
| Intermediate state visible | No (locked until commit) | Yes (steps visible before completion) |
| Implementation complexity | Low protocol, high infra cost | Higher business logic (compensation design) |
| Best fit | Co-located DB nodes, short txns | Microservices, long-running workflows |
Correctly describes both phases of 2PC, identifies the blocking/in-doubt problem, explains Saga compensation concept, distinguishes choreography from orchestration.
Explains why 2PC blocks (coordinator crash after PREPARE), articulates that Saga provides eventual not strong consistency, explains compensation as semantic undo not rollback, discusses idempotency requirements, and makes a concrete recommendation on when to use each.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment