SA-301b · Module 2
Distributed Transactions with Sagas
3 min read
In a monolith, a database transaction spans the entire operation: deduct inventory, charge payment, create shipment — all or nothing. In microservices, each step is owned by a different service with a different database. There is no distributed transaction that spans all three. The saga pattern replaces the single transaction with a sequence of local transactions, each with a compensating action that undoes its effect if a later step fails.
- Choreography Each service publishes an event when it completes its step, and the next service reacts. OrderPlaced triggers InventoryReserved, which triggers PaymentCharged, which triggers ShipmentCreated. No central coordinator. The services collaborate through events. The advantage: no single point of failure. The disadvantage: the transaction flow is distributed across multiple services and harder to observe and debug.
- Orchestration A saga orchestrator coordinates the transaction. It tells the inventory service to reserve, waits for confirmation, tells the payment service to charge, waits for confirmation, tells the shipping service to create the shipment. If any step fails, the orchestrator triggers compensating actions in reverse order. The advantage: the transaction flow is centralized and observable. The disadvantage: the orchestrator is a critical dependency.
- Compensating Actions Every step in a saga must have a compensating action — the reverse operation that undoes its effect. InventoryReserved is compensated by InventoryReleased. PaymentCharged is compensated by PaymentRefunded. The compensating action must be idempotent because it may be triggered multiple times during failure recovery. Design compensations as carefully as the forward actions.