Saga
Coordinates long-running transactions across services using steps and compensations.
Context
A business process spans multiple services (Payment, Inventory, Shipping). Distributed transactions (2PC) do not scale.
Problem
Without a coordinator, there's no way to roll back partial steps if something fails halfway through.
Solution
The Saga executes a sequence of local steps. If one fails, it executes its compensations in reverse order.
#Variants
- Orchestrated: A central coordinator dictates each step.
- Choreographed: Each service reacts to events from others.
#C# Example — Orchestrated Saga
public class PlaceOrderSaga
{
public async Task RunAsync(PlaceOrderCommand cmd)
{
var orderId = await _orders.CreateAsync(cmd);
try
{
await _payments.ChargeAsync(orderId, cmd.Total);
await _inventory.ReserveAsync(orderId, cmd.Items);
await _shipping.ScheduleAsync(orderId);
}
catch
{
// Compensations in reverse order
await _shipping.CancelAsync(orderId);
await _inventory.ReleaseAsync(orderId);
await _payments.RefundAsync(orderId);
await _orders.MarkFailedAsync(orderId);
throw;
}
}
}Tradeoffs
| Pro | Con |
|---|---|
| No distributed transactions | Each step requires its compensation |
| Saga state is persistent and resumeable | Designing idempotent compensations is difficult |
#extra #distributed #transaction