SAGA

SAGA

Part 6: Saga Pattern - Complete Guide to Distributed Transactions

Part 6: Saga Pattern

Managing Distributed Transactions Across Microservices - Complete Guide

πŸ“Œ Quick Summary (30 seconds):
Saga pattern manages distributed transactions across microservices using a sequence of local transactions, each with a compensating action. Two implementations: Choreography (decentralized, event-driven) and Orchestration (centralized coordinator). Choose choreography for simplicity, orchestration for complex workflows with visibility needs.

❓ The Problem: No Distributed Transactions in Microservices

Why can't we use traditional ACID transactions?
  • No shared database between services
  • Distributed transactions (2PC/XA) don't scale well
  • Locks would be held across services (performance killer)
  • Network failures make coordination impossible (CAP theorem)

πŸ”„ What is a Saga?

Saga = Sequence of Local Transactions + Compensations

Step 1: Order Service ──► Create Order (PENDING)
β”‚
β–Ό
Step 2: Payment Service ──► Process Payment
β”‚
β–Ό
Step 3: Inventory Service ──► Reserve Stock
β”‚
β–Ό
Step 4: Shipping Service ──► Create Shipment
β”‚
β–Ό
βœ… SUCCESS - Order Complete

IF ANY STEP FAILS:

Step 3 fails (Out of Stock)
β”‚
β–Ό
Compensation 2: Payment Service ──► Refund Payment
β”‚
β–Ό
Compensation 1: Order Service ──► Cancel Order
β”‚
β–Ό
❌ Order Cancelled - Rollback Complete

πŸ“Š Saga vs ACID Transaction

FeatureACID TransactionSaga Pattern
Database ScopeSingle DatabaseMultiple Services
Consistency ModelStrong (ACID)Eventual (BASE)
LockingYes (holds locks)No (no locks)
IsolationSerializableNo isolation (dirty reads possible)
ScalabilityLimitedHigh
Failure HandlingAutomatic RollbackCompensating Transactions
ComplexityLowHigh
Best ForSingle service operationsCross-service workflows

🎭 1. Choreography (Event-Driven Saga)

Choreography Flow - No Central Controller

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Order β”‚ ──event: OrderCreated──► β”‚ Payment β”‚
β”‚ Service β”‚ β”‚ Service β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
β”‚ event: PaymentSuccess
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Shipping β”‚ ◄──event: StockReserved── β”‚ Inventory β”‚
β”‚ Service β”‚ β”‚ Service β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
βœ… PROS
  • No central point of failure
  • Simple to implement for linear flows
  • Good scalability (decentralized)
  • Loose coupling between services
  • Easy to add new participants
❌ CONS
  • Hard to debug (no central view)
  • Risk of cyclic dependencies
  • Complex error handling
  • No central audit trail
  • Hard to manage complex workflows

🎼 2. Orchestration (Central Coordinator Saga)

Orchestration Flow - Central Coordinator

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SAGA ORCHESTRATOR β”‚
β”‚ (Central Coordinator) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚ β”‚ β”‚ β”‚
β–Ό β–Ό β–Ό β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Order β”‚ β”‚ Payment β”‚ β”‚ Inventory β”‚ β”‚ Shipping β”‚ β”‚ User β”‚
β”‚ Service β”‚ β”‚ Service β”‚ β”‚ Service β”‚ β”‚ Service β”‚ β”‚ Service β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Orchestrator tracks state and knows which step to execute next. If a step fails, Orchestrator triggers compensations in reverse order.
βœ… PROS
  • Central visibility and control
  • Easier to debug (single place to check)
  • Clear audit trail
  • Simpler error handling
  • Supports complex branching logic
❌ CONS
  • Orchestrator is a single point of failure
  • Can become performance bottleneck
  • More infrastructure complexity
  • Orchestrator business logic can grow complex
  • Centralized = potential coupling

πŸ“‹ Choreography vs Orchestration - Quick Comparison

AspectChoreographyOrchestration
ControlDecentralizedCentralized
CommunicationEventsCommands (sync/async)
VisibilityLow (hard to trace)High (central logs)
DebuggingDifficultEasier
ScalabilityExcellentLimited by orchestrator
Single Point of FailureNoYes (orchestrator)
Complex WorkflowsHard to manageWell suited
Cyclic Dependencies RiskHighLow
Best ForSimple, linear workflowsComplex, branching workflows

πŸ”„ Compensating Transactions Reference

⚠️ Golden Rule: Every step in a saga MUST have a compensating action defined.
Forward TransactionCompensating ActionIdempotent?Example
Create OrderCancel OrderYes (orderId)Set status to CANCELLED
Process PaymentRefund PaymentYes (paymentId)Reverse charge on card
Reserve StockRelease StockYes (reservationId)Add stock back to inventory
Book HotelCancel BookingYes (bookingId)Free up the room
Send EmailSend Reversal EmailYes (emailId)Send cancellation notice
Book FlightCancel FlightYes (PNR)Refund or credit voucher
Update CacheRevert/Invalidate CacheYes (cacheKey)Remove or restore old value

🎯 When to Use Choreography vs Orchestration

🎭 Choose Choreography When:
  • Workflow has 2-4 steps (simple and linear)
  • Teams want full autonomy
  • You have good event-driven infrastructure (Kafka, RabbitMQ)
  • No need for central audit trail
  • Services can work independently
  • Low coordination overhead needed
πŸ“Œ Example: Order β†’ Payment β†’ Inventory (linear)
🎼 Choose Orchestration When:
  • Workflow has complex branching/conditional logic
  • Central visibility and audit trail required
  • Multiple sagas share common steps
  • Need ability to resume sagas after failures
  • Compliance requires transaction logs
  • Business rules change frequently
πŸ“Œ Example: Travel booking with flights, hotels, cars, insurance (branching)

✈️ Real-World Examples

IndustryExample SagaStepsCompensations
E-Commerce Order Processing Order β†’ Payment β†’ Inventory β†’ Shipping Cancel Order β†’ Refund β†’ Release Stock β†’ Cancel Shipment
Travel Booking Trip Reservation Flight β†’ Hotel β†’ Car β†’ Insurance Cancel Flight β†’ Cancel Hotel β†’ Cancel Car β†’ Cancel Insurance
Banking Fund Transfer Debit Account A β†’ Credit Account B Credit Account A β†’ Debit Account B
Insurance Claim Processing Validate β†’ Approve β†’ Pay β†’ Notify Reverse Validation β†’ Reject β†’ Recover Payment β†’ Recall Notification

⚠️ Common Pitfalls and Solutions

PitfallSymptomSolution
Non-idempotent operationsDuplicate payments on retryUse idempotency keys + unique database constraints
Missing compensationsPartial rollback, data inconsistencyDesign compensation for EVERY forward step
Long-running sagasResource locks, degraded performanceAdd timeouts, checkpoints, resume capability
No visibilityCannot debug failuresCentral saga state repository + monitoring dashboard
Compensation failureStuck in inconsistent stateDead letter queue + manual intervention alerts
No timeout handlingSaga never completesImplement saga timeouts and scheduled compensation
Shared database between servicesServices not independentEnforce database per service

πŸ”‘ Idempotency in Sagas (Critical!)

Why Idempotency Matters: The same compensation may be called multiple times due to network retries.
Idempotent vs Non-Idempotent Operations

βœ… IDEMPOTENT (Safe to retry):
β€’ SET balance = 1000 β†’ Same result every time
β€’ UPDATE status = 'CANCELLED' WHERE id = 123
β€’ DELETE FROM cart WHERE user_id = 456

❌ NON-IDEMPOTENT (NOT safe to retry):
β€’ ADD 100 to balance β†’ Each retry adds another 100
β€’ INSERT INTO orders β†’ Each retry creates duplicate
β€’ UPDATE balance = balance + 100 β†’ Same problem

βœ… Saga Best Practices

Design & Implementation
  • Design compensations FIRST, then forward transactions
  • Make ALL operations idempotent (use idempotency keys)
  • Store saga state persistently (database, not just memory)
  • Implement timeouts for every step
  • Monitor sagas actively (detect stuck/long-running)
Testing & Operations
  • Test compensation paths as thoroughly as success paths
  • Keep sagas short (fewer steps = lower failure probability)
  • Log every step with correlation ID
  • Implement dead letter queue for failed compensations
  • Have manual intervention plan for unrecoverable states

πŸ› οΈ Popular Saga Frameworks

FrameworkTypeLanguageKey Feature
Axon FrameworkOrchestrationJavaEvent Sourcing + CQRS built-in
CamundaOrchestration (BPMN)JavaVisual workflow designer
Temporal.ioOrchestrationJava/GoDurable execution, fault tolerance
Apache KafkaChoreographyAnyEvent-driven sagas
Spring CloudBothJavaSpring ecosystem integration
MassTransitBoth.NET.NET ecosystem

πŸ’‘ Interview Power Phrases

"Saga replaces ACID with eventual consistency using compensating transactions. Each step has a corresponding compensation that undoes its effect if later steps fail."
"We use choreography for simple, linear workflows where services can work independently. We use orchestration for complex workflows where central visibility and audit trail are required."
"The hardest part of sagas isn't the forward path - it's the compensation. If you can't design a safe compensating transaction, you shouldn't split that operation into a separate microservice."
"All operations in a saga must be idempotent. We use idempotency keys to ensure that retries don't cause duplicate effects."

πŸ“š Quick Memory Reference

πŸ”‘ Key Terms
  • Saga - Sequence of local transactions
  • Compensation - Undo operation for each step
  • Choreography - Decentralized, event-driven
  • Orchestration - Centralized coordinator
  • Idempotency - Safe retries
  • Eventually Consistent - BASE not ACID
🧠 Mental Models
  • ACID = Single chef in one kitchen
  • Saga = Multiple chefs coordinating via messages
  • Choreography = Dancers without a leader
  • Orchestration = Conductor leading the orchestra
  • Compensation = Undo button for each action
πŸ“Œ One-Line Summary

"Saga replaces distributed transactions with compensations - trade ACID for BASE, locks for events, strong consistency for eventual consistency."

βœ… Key Takeaways (Remember These 5 Points)

  • Saga β‰  ACID - No locks, eventual consistency, compensations instead of rollback
  • Two patterns: Choreography (decentralized events) vs Orchestration (central coordinator)
  • Every step needs a compensation - Design forward and backward together
  • Idempotency is mandatory - Same operation multiple times = same result
  • Store saga state - For recovery, monitoring, and debugging
🎯 Remember This:
Choreography = Simple, scalable, hard to debug
Orchestration = Complex, visible, centralized control
Both = Compensations + Idempotency + Eventual Consistency