Design Patterns & Practices  

🌀 Saga Design Pattern - Orchestration Saga – Cheat Sheet

Category: Distributed Transactions / Microservices
Problem: How to maintain data consistency across multiple microservices without 2PC (two-phase commit).
Solution: Break long transactions into a series of local transactions. Each has a compensating action (undo) if something fails.

🔑 Key Points

  • Orchestration Saga → Central coordinator tells services what to do.

  • Choreography Saga → Services listen to events and react accordingly.

  • Each step = Local transaction + Possible compensating action.

🖥️ C# Example – E-Commerce Order (Orchestration Saga)

Scenario:

  1. Place Order

  2. Reserve Payment

  3. Update Inventory

  4. If failure → rollback via compensating transactions

// Step definitions
public interface ISagaStep
{
    Task ExecuteAsync();
    Task CompensateAsync();
}

public class PaymentStep : ISagaStep
{
    public async Task ExecuteAsync() => Console.WriteLine("✅ Payment Reserved");
    public async Task CompensateAsync() => Console.WriteLine("❌ Payment Refunded");
}

public class InventoryStep : ISagaStep
{
    public async Task ExecuteAsync() => Console.WriteLine("✅ Inventory Updated");
    public async Task CompensateAsync() => Console.WriteLine("❌ Inventory Restored");
}

// Orchestrator
public class SagaOrchestrator
{
    private readonly List<ISagaStep> _steps = new();
    public void AddStep(ISagaStep step) => _steps.Add(step);

    public async Task ExecuteAsync()
    {
        var executedSteps = new Stack<ISagaStep>();
        try
        {
            foreach (var step in _steps)
            {
                await step.ExecuteAsync();
                executedSteps.Push(step);
            }
            Console.WriteLine("🎉 Saga Completed Successfully!");
        }
        catch
        {
            Console.WriteLine("⚠️ Error! Starting Compensation...");
            while (executedSteps.Count > 0)
                await executedSteps.Pop().CompensateAsync();
        }
    }
}

Usage:

var saga = new SagaOrchestrator();
saga.AddStep(new PaymentStep());
saga.AddStep(new InventoryStep());
await saga.ExecuteAsync();

🌍 Real-World Example

  • Flight Booking System

    • Book Flight ✈️

    • Reserve Hotel 🏨

    • Rent Car 🚗

    • If Hotel fails → Cancel Flight & Car

📌 Remember in Interview

  • Saga = Long transaction broken into smaller steps.

  • Each step = do + undo (compensating action).

  • Two styles: Orchestration (central brain) vs Choreography (event-driven).

  • Prevents inconsistency in distributed microservices.