# Sagas Long-running workflows with compensation logic for distributed transactions. ## Overview Sagas coordinate multiple steps in a workflow, with compensation logic to handle failures. They listen to events, execute business logic, and publish new events to continue the workflow. **Key Features:** - ✅ **ISaga** - Interface for saga implementations - ✅ **Multi-Step Workflows** - Coordinate complex processes - ✅ **Compensation** - Rollback on failures - ✅ **State Management** - Track saga progress - ✅ **Event-Driven** - React to domain events ## Quick Start ```csharp public class OrderFulfillmentSaga : ISaga { private readonly IEventStreamStore _eventStore; private readonly IInventoryService _inventoryService; private readonly IPaymentService _paymentService; private readonly IShippingService _shippingService; public async Task HandleAsync(OrderPlacedEvent @event, CancellationToken ct) { try { // Step 1: Reserve inventory await _inventoryService.ReserveAsync(@event.OrderId, @event.Items); await PublishEventAsync(new InventoryReservedEvent { OrderId = @event.OrderId }); // Step 2: Process payment await _paymentService.ChargeAsync(@event.OrderId, @event.TotalAmount); await PublishEventAsync(new PaymentProcessedEvent { OrderId = @event.OrderId }); // Step 3: Ship order await _shippingService.ShipAsync(@event.OrderId); await PublishEventAsync(new OrderShippedEvent { OrderId = @event.OrderId }); } catch (Exception ex) { // Compensation: Rollback await CompensateAsync(@event.OrderId); await PublishEventAsync(new OrderFailedEvent { OrderId = @event.OrderId, Reason = ex.Message }); } } private async Task CompensateAsync(int orderId) { // Release inventory await _inventoryService.ReleaseAsync(orderId); // Refund payment await _paymentService.RefundAsync(orderId); } private async Task PublishEventAsync(object @event) { await _eventStore.AppendAsync("orders", new[] { @event }); } } ``` ## Saga Pattern ``` OrderPlacedEvent ↓ Reserve Inventory ↓ InventoryReservedEvent ↓ Process Payment ↓ PaymentProcessedEvent ↓ Ship Order ↓ OrderShippedEvent (If any step fails → Compensate all previous steps) ``` ## Features ### [Saga Pattern](saga-pattern.md) Understand the saga pattern and when to use it. ### [Creating Sagas](creating-sagas.md) Implement ISaga for long-running workflows. ### [Compensation](compensation.md) Handle failures with rollback logic. ## Common Use Cases **Order Fulfillment:** ``` Place Order → Reserve Inventory → Charge Payment → Ship Order (Compensation: Release Inventory → Refund Payment) ``` **User Registration:** ``` Register → Send Verification Email → Wait for Confirmation → Activate Account (Compensation: Delete User → Cancel Email) ``` **Booking System:** ``` Book Flight → Reserve Hotel → Charge Payment → Send Confirmation (Compensation: Cancel Flight → Cancel Hotel → Refund Payment) ``` ## Best Practices ### ✅ DO - Implement compensation for each step - Use idempotent operations - Store saga state - Monitor saga completion - Test failure scenarios ### ❌ DON'T - Don't forget compensation logic - Don't assume steps always succeed - Don't skip state persistence - Don't create circular dependencies ## See Also - [Event Streaming Overview](../README.md) - [Events and Workflows](../fundamentals/events-and-workflows.md) - [Projections](../projections/README.md)