← Week 2: Distributed Transactions

Day 9: Three-Phase Commit and Sagas

Phase 4 · Jul 30, 2026

← Week 2: Distributed Transactions

Agenda (2–3 hours)

  • Read (45 min): Skeen "A Quorum-Based Commit Protocol" (1982) on 3PC; Garcia-Molina & Salem "Sagas" (1987)
  • Study (45 min): Draw the 3PC state machine; identify the additional phase and why it prevents the blocking problem
  • Practice (45 min): Sketch a Saga for an e-commerce order: define forward transactions and compensation transactions for each step
  • Challenge (30 min): What does 3PC sacrifice to avoid blocking? Why do most production systems use Sagas instead of 3PC?
← Week 2: Distributed Transactions

Three-Phase Commit

3PC adds a PRE-COMMIT phase between PREPARE and COMMIT to eliminate blocking:

  1. Phase 1 (CanCommit): coordinator asks "can you commit?" — no locks yet
  2. Phase 2 (PreCommit): coordinator sends PRE-COMMIT — cohorts lock resources and ack
  3. Phase 3 (DoCommit): coordinator sends COMMIT — cohorts apply and release locks

How 3PC eliminates blocking:

  • If coordinator crashes after PreCommit, any cohort that received PRE-COMMIT can unilaterally commit (they know all cohorts voted yes)
  • If coordinator crashes before PreCommit, cohorts can safely abort (not all votes were in)

Problem: 3PC assumes no network partitions — in a partition, a cohort that received PreCommit and a cohort that didn't can simultaneously commit and abort. Not safe in practice.

← Week 2: Distributed Transactions

Sagas: An Alternative Approach

A Saga is a sequence of local transactions, each with a corresponding compensation:

Order Saga:
  T1: Reserve inventory        → C1: Release inventory reservation
  T2: Charge payment card      → C2: Refund payment
  T3: Create shipment          → C3: Cancel shipment
  T4: Send confirmation email  → (no compensation: email already sent)

If T3 fails: execute C2 → C1 in reverse order (backward recovery).
The final state is always consistent — either fully committed or fully compensated.

← Week 2: Distributed Transactions

Choreography vs Orchestration

Choreography: services react to events; no central coordinator

InventoryService publishes "inventory-reserved" →
PaymentService listens, charges card, publishes "payment-charged" →
ShipmentService listens, creates shipment

Orchestration: a saga orchestrator explicitly calls each step

SagaOrchestrator:
  1. Call InventoryService.reserve()
  2. If ok: call PaymentService.charge()
  3. If ok: call ShipmentService.create()
  4. On any failure: call compensations in reverse

Orchestration is easier to reason about and debug; choreography is more decoupled.

← Week 2: Distributed Transactions

When to Use What

Pattern Use when
2PC Strong atomicity required; latency matters less than consistency; shared infrastructure
3PC Rarely used in practice
Saga (choreography) Loosely coupled services; event-driven architecture
Saga (orchestration) Complex saga logic; need visibility into state; easier debugging

Most modern microservice architectures use sagas with orchestration for distributed business transactions.

← Week 2: Distributed Transactions

Key Takeaways

  • 3PC eliminates blocking but is unsafe under network partitions — rarely used in practice
  • Sagas decompose distributed transactions into compensatable local transactions
  • Choreography: event-driven, decoupled; Orchestration: explicit control, observable
  • The key constraint of sagas: each step must be idempotent and must have a compensation

Tomorrow: sagas in depth — implementation patterns and failure handling.