The Saga Pattern: Distributed Consistency without 2PC
In a microservices architecture, a single business process (e.g., "Order Fulfillment") often spans multiple services, each with its own database. Traditional **Two-Phase Commit (2PC)** is often avoided in 2026 due to its blocking nature and poor scalability. The **Saga Pattern** provides an alternative by treating a distributed transaction as a sequence of local transactions.
1. Core Concept
A Saga is a sequence of local transactions $T_1, T_2, ..., T_n$. Each local transaction updates the database and publishes an event or message to trigger the next step.
* **Success Path:** If all $T_i$ succeed, the business process is complete.
* **Failure Path:** If $T_i$ fails, the Saga must execute **Compensating Transactions** $C_{i-1}, ..., C_1$ to undo the changes made by the preceding steps.
2. Implementation Strategies
A. Choreography (Event-Based)
There is no central coordinator. Each service produces and listens to events from other services.
* **Pros:** Highly decoupled; easy to add/remove participants.
* **Cons:** Can lead to "spaghetti events" where the business flow is hard to visualize.
B. Orchestration (Command-Based)
A central **Orchestrator** (State Machine) manages the Saga logic. It sends commands to services and handles their responses.
* **Pros:** Centralized visibility; easy to implement complex logic (parallel steps, conditional branches).
* **Cons:** Risk of a "distributed monolith" if the orchestrator becomes too heavy.
* **2026 Standard:** Use for workflows with 4+ steps or strict audit requirements (e.g., via *Temporal* or *AWS Step Functions*).
3. The 2026 Transaction Model
To simplify recovery, modern Sagas categorize steps into three types:
| Type | Description |
| :--- | :--- |
| **Compensatable** | Steps that can be undone (e.g., "Reserve Item"). Requires a matching $C_i$. |
| **Pivot** | The "Point of No Return." If this succeeds, the Saga *must* complete. |
| **Retriable** | Steps after the pivot (e.g., "Send Receipt"). Designed to eventually succeed via retries. |
4. Critical Dependencies
Sagas are fragile without two supporting patterns:
1. **Transactional Outbox:** Ensures the database update and event publication happen atomically.
2. **Idempotent Consumers:** Ensures that retrying an event (at-least-once delivery) does not result in duplicate side effects (e.g., charging a customer twice).
See Also
* [Distributed Systems Hub](DistributedSystemsHub) — Pattern catalog.
* [CQRS and Event Sourcing](CQRSAndEventSourcing) — Often used to store Saga state.
* [Idempotent Receiver](IdempotentReceiver) — Mandatory for Saga participants.