Central orchestrator coordinates distributed transaction: Order, Payment, Inventory, Shipping with compensating rollbacks
Saga Orchestration is a design pattern for managing distributed transactions across multiple microservices. A central Orchestrator coordinates the entire transaction by issuing commands to participant services in a defined sequence and handling failures through compensating transactions executed in reverse order.
Traditional two-phase commit (2PC) does not work well over HTTP-based microservices due to latency, partial failures, and tight coupling. The Saga pattern breaks a distributed transaction into a series of local transactions, each owned by a single service. Orchestration places the coordination logic in one dedicated component -- the Orchestrator -- which knows the full workflow and drives each step forward or backward.
This pattern is the foundation of several production workflow engines:
The central coordinator that manages the lifecycle of a saga. It maintains a Saga Log to track which steps have been executed and their outcomes. On failure, it reads the log to determine which compensating transactions must run and in what order.
Each microservice owns a local transaction and its corresponding compensating action:
| Service | Forward Action | Compensating Action |
|---|---|---|
| Order Service | Create order (status=PENDING) | Cancel order (status=CANCELLED) |
| Payment Service | Charge payment | Refund payment |
| Inventory Service | Reserve stock | Release stock |
| Shipping Service | Schedule shipment | Cancel shipment |
A persistent record of every step in the saga. The Orchestrator writes to the log before and after each step, enabling recovery after crashes. If the Orchestrator restarts, it can resume or compensate from the last recorded state.
The Orchestrator communicates with services via synchronous HTTP commands (request/reply). Each service performs its local transaction against its own database and reports success or failure back to the Orchestrator.
Unlike choreography where services react to events, orchestration uses explicit commands. The Orchestrator sends a command (e.g., ChargePayment) and waits for a response. This makes the flow deterministic and easy to reason about.
Every forward step must have a corresponding compensating action that semantically undoes the work. Compensations are not rollbacks -- they are new transactions that reverse the business effect. For example, a payment refund is a new transaction, not an undo of the original charge.
When a step fails, the Orchestrator executes compensations in reverse order for all previously completed steps. If step 3 fails, it compensates step 2 first, then step 1. This preserves referential integrity between services.
All commands and compensations must be idempotent. Network failures can cause retries, and the Orchestrator may re-send commands. Services must handle duplicate requests gracefully, typically by checking saga/step IDs before executing.
The Orchestrator and its Saga Log provide a single place to observe the state of any transaction. Operators can query the log to see which step a saga is on, whether it succeeded or is compensating, and which services have been contacted.
Saga Orchestration is well-suited for:
Consider Saga Choreography instead when: