Saga basics
Saga — Full Revision Summary¶
What is it?¶
A pattern for managing transactions that span multiple microservices, where each service has its own database and a single DB transaction is impossible.
Core idea: Break the transaction into sequential steps. Define a compensating action for every step. If anything fails, execute compensations in reverse order.
The two approaches:¶
Choreography¶
No central controller. Services react to events and know what to listen to.
Each service:
- Publishes what it did ("PaymentCharged")
- Listens for failure events ("StockDeductionFailed")
- Knows its own compensation (refund if stock failed)
Pros: Simple, no extra infrastructure, loosely coupled.
Cons: Flow is spread across services, hard to follow, hard to debug as it grows.
Orchestration¶
A central orchestrator owns the flow. It consumes result events and issues commands.
Orchestrator:
- Listens to result events ("PaymentCharged", "StockDeductionFailed")
- Issues commands ("ChargePayment", "RefundPayment")
- Tracks saga state in a DB row per saga instance
The individual services have no idea they're part of a saga — they just receive a command, do their job, publish a result.
Pros: Flow is visible in one place, easier to debug, handles complex scenarios.
Cons: Extra service to maintain, orchestrator can be a single point of failure.
The Saga State Machine (Orchestration only):¶
Every saga instance has a row in a DB table tracking its current state and what steps completed.
| CorrelationId | CurrentState | PaymentCharged | StockDeducted |
|---------------|------------------|----------------|---------------|
| abc-123 | Compensating | true | false |
This gives the orchestrator memory — critical for knowing what to compensate after a crash or out-of-order events.
How RabbitMQ fits in:¶
RabbitMQ is just the transport. Every participant including the orchestrator is just a publisher and consumer with its own queue. Nobody blocks waiting for responses — everything is fire and forget, responses come back as separate messages.
What makes Saga reliable in practice:¶
- Outbox pattern — events are never lost even if service crashes after DB write
- Idempotency — retries don't cause duplicate actions
- State tracking — always know where the saga is, survive crashes
The trade-off to always mention:¶
Saga gives you eventual consistency, not strong consistency. There's a window where data is partially updated across services. That's the accepted trade-off in microservices.
One line summary:¶
"Saga manages cross-service transactions by defining steps with compensating actions, coordinated either via events between services (choreography) or a central orchestrator, ensuring the system can always cleanly undo partial work on failure."