Skip to content

Saga vs Two-Phase Commit (2PC)

1. Decision

Choose Two-Phase Commit (2PC) for strict ACID transactional consistency across tightly coupled homogeneous database nodes where blocking locks and high network availability are acceptable; choose the Saga Pattern (Choreography or Orchestration) for distributed transactions across independent microservices and heterogeneous databases where loose coupling, high availability, and eventual consistency are required.


2. 30-Second Answer

Managing distributed transactions across multiple microservices or database shards requires choosing between 2PC and Saga. Two-Phase Commit (2PC) is a synchronous protocol where a central Coordinator coordinates a Prepare Phase and Commit Phase across participating nodes. 2PC guarantees strict ACID isolation across databases, but holds blocking locks on resources, creating a single point of failure (coordinator dependency) and severe latency degradation. Saga Pattern breaks a global transaction into a sequence of local ACID transactions executed by independent microservices. Each local transaction updates its local database and emits an event. If a step fails, the Saga executes explicit Compensating Transactions in reverse order to roll back state. Saga trades ACID isolation for eventual consistency and high availability.


3. Decision Matrix

Option Best For Avoid When Latency Scalability Consistency Operational Complexity
Two-Phase Commit (2PC) Tightly coupled homogeneous database shards (XA transactions, Spanner), short-lived distributed ACID updates Independent microservice architectures, high-scale internet traffic, heterogeneous polyglot databases High (Synchronous multi-roundtrip blocking network locks) Low (Blocking locks reduce cluster concurrency; coordinator SPOF) Strict ACID (Immediate global consistency) High (Coordinator failover, lock management)
Saga (Choreography) Simple event-driven microservice workflows (2-4 steps), asynchronous event-bus architectures Complex workflows with 10+ steps (becomes impossible to trace event cascades) Low (Asynchronous non-blocking execution) High (Decoupled independent microservices) Eventual Consistency (Compensating rollbacks) Medium
Saga (Orchestration) Complex multi-step microservice transactions (5+ steps), centralized workflow management (Temporal / Step Functions) Simple 2-step workflows where adding a dedicated orchestrator service is unnecessary Low to Medium (Central orchestrator manages async step transitions) High (Decoupled execution with central visibility) Eventual Consistency (Compensating rollbacks) Medium

4. Selection Rules

Requirement Best Choice Rationale / Example
Microservice E-Commerce Order Fulfillment Saga (Orchestration) Order Service orchestrates Payment, Inventory, and Shipping microservices
Homogeneous Database Shard Commit (XA) Two-Phase Commit (2PC) Relational database engine coordinates atomic commit across 2 physical storage shards
Avoid Resource Locks Across Microservices Saga Pattern Local transactions commit immediately; no cross-service database locks are held
Complex 8-Step Business Workflow Saga (Orchestration) Orchestrator (Temporal.io) tracks state transitions, timeouts, and compensation steps
Simple 2-Step Event Cascade (Order \(\rightarrow\) Email) Saga (Choreography) Order service publishes OrderCreated; Email service listens and sends confirmation

5. Tradeoffs

  1. ACID Isolation vs Eventual Consistency
  2. Gain (2PC): Transactions are fully isolated; dirty reads and intermediate states are impossible.
  3. Lose (2PC): Holding blocking locks degrades system throughput and causes deadlocks.
  4. High Availability vs Synchronous Lock Coordination
  5. Gain (Saga): Local transactions commit instantly; system remains available even if downstream services crash.
  6. Lose (Saga): Intermediate dirty states are visible to users before compensation completes.
  7. Choreography Simplicity vs Event Cascade Chaos
  8. Gain (Choreography): Loose coupling; no single central orchestrator service to maintain.
  9. Lose (Choreography): Cyclic event dependencies and difficult post-mortem tracing across 10+ services.
  10. Orchestration Central Visibility vs Coordinator Dependency
  11. Gain (Orchestration): Centralized state machine, clear workflow status, and explicit compensation rules.
  12. Lose (Orchestration): Introduces a dedicated orchestrator service dependency.
  13. Compensating Transactions Complexity
  14. Gain (Saga): Reverts state asynchronously without holding long-lived database locks.
  15. Lose (Saga): Writing idempotent compensating logic (e.g. refunding credit card) is error-prone.

6. Interview Counter Questions

  1. How do the Prepare Phase and Commit Phase work in Two-Phase Commit (2PC)?
  2. What is the Blocking Coordinator Problem in 2PC and how does Three-Phase Commit (3PC) attempt to fix it?
  3. What is the difference between Saga Choreography and Saga Orchestration?
  4. How do Compensating Transactions work in a Saga pattern when step 3 of a 5-step workflow fails?
  5. Why lacks Isolation (the 'I' in ACID) in the Saga Pattern and how do you mitigate dirty reads?
  6. How does Temporal.io / AWS Step Functions implement Saga Orchestration?
  7. What happens if a Compensating Transaction itself fails in a Saga?
  8. Why is 2PC considered an anti-pattern for microservices across different team boundaries?
  9. What is an Out-of-Order Execution in Saga Choreography and how do sequence tokens fix it?
  10. How do semantic locks or pivot transactions mitigate lack of isolation in Sagas?

7. Gold Standard Answers

  1. Prepare Phase: Coordinator asks all nodes "Can you commit?". Nodes acquire locks, write WAL, and reply YES/NO. Commit Phase: If all reply YES, Coordinator sends COMMIT; if any reply NO, Coordinator sends ABORT.
  2. If the Coordinator crashes after nodes reply YES in Prepare Phase, nodes remain blocked holding locks indefinitely. 3PC adds a Pre-Commit state and timeouts to prevent blocking, but fails over unreliable networks.
  3. Choreography: Microservices communicate asynchronously via events without a central controller (Service A publishes EventA \(\rightarrow\) Service B listens and acts). Orchestration: A central service tells each microservice explicitly which action to execute.
  4. When step 3 fails, the Saga manager catches the error and executes compensating transactions for completed steps in reverse order: Compensate Step 2 \(\rightarrow\) Compensate Step 1 (e.g., Cancel Payment \(\rightarrow\) Release Inventory).
  5. Sagas commit local transactions immediately, exposing intermediate states. Mitigate using: (1) Semantic Locks (flag record as PENDING_APPROVAL), (2) Commutative updates, (3) Reread-verify checks before final actions.
  6. Temporal maintains an event-sourced durable state machine. It executes workflow code as a sequence of deterministic steps, automatically tracking retries, timeouts, and executing compensation functions on failure.
  7. Compensating transactions must be designed to be idempotent and retried infinitely until success. If retry limits are exceeded, raise P1 alerts to a Dead-Letter Queue (DLQ) for manual operational intervention.
  8. 2PC couples database schemas and execution threads across service boundaries over the network. If Team B's service slows down, Team A's database locks remain open, breaking service autonomy.
  9. Out-of-order events occur when Event 3 arrives before Event 2. Inject monotonically increasing sequence tokens or version IDs into event payloads so consumers reject or queue out-of-order events.
  10. A Pivot Transaction is the point-of-no-return in a Saga. Steps before the pivot must have compensations. Once the pivot transaction commits, subsequent steps cannot fail and must execute to completion.

8. Common Mistakes

  • Using 2PC across independent microservices owned by different teams, creating cascading lock outages.
  • Assuming Saga Pattern provides ACID isolation out-of-the-box without handling dirty reads via pending status flags.
  • Writing non-idempotent Compensating Transactions (e.g., executing duplicate refunds when retrying compensation).
  • Choosing Saga Choreography for complex 10+ step workflows, resulting in un-debuggable "spaghetti event" architectures.
  • Forgetting to handle cases where a compensating transaction fails permanently.

9. Keywords

Two-Phase Commit (2PC), Three-Phase Commit (3PC), Saga Pattern, Choreography, Orchestration, Compensating Transaction, Pivot Transaction, Semantic Lock, Temporal.io, AWS Step Functions, XA Transactions, Prepare Phase, Commit Phase, Dirty Reads.


10. Cheat Sheet

  • 2PC (Two-Phase Commit): Synchronous 2-phase lock coordination (Prepare + Commit). Guarantees ACID isolation, but blocking locks destroy availability & throughput. (Use for DB engine internal shards only).
  • Saga Pattern: Sequence of local ACID transactions with async Compensating Transactions on failure. High availability & loose coupling, but eventual consistency. (Use for Microservices).
  • Choreography vs Orchestration: Choreography = Simple event-driven cascades (2-4 steps); Orchestration = Centralized state machine manager (5+ steps e.g. Temporal.io).
  • Compensating Rule: All compensating transactions MUST be Idempotent and retried until success.
  • Isolation Fix: Lack of Saga isolation \(\rightarrow\) use Semantic Locks (status = PENDING_PAYMENT) to prevent dirty reads.
  • Pivot Transaction: The point of no return in a Saga. Once the pivot commits, downstream steps CANNOT fail.

11. Related Decisions