Day 44: The Saga Pattern: Choreography Style.

Spring Boot Microservices: From Design to Deployment ~9 min read 60 min hands-on

Day 44: The Saga Pattern: Choreography Style

Welcome back, architects and engineers! Today, we're diving deep into a pattern that separates the contenders from the champions in the world of hyperscale microservices: The Saga Pattern, specifically its Choreography style. If you’ve ever wondered how titans like Amazon or Netflix manage complex, multi-step business processes across dozens or hundreds of services without everything grinding to a halt, you're about to uncover a key piece of that puzzle.

The journey from a monolithic application to a distributed microservices ecosystem often feels like trading a cozy single-family home for a bustling, interconnected city. While microservices bring immense benefits in terms of scalability and independent deployment, they introduce a formidable challenge: distributed transactions. How do you ensure a complex business process, like an e-commerce order, either fully completes across multiple services or is completely rolled back, when each service owns its own data and operates independently?

The Distributed Transaction Conundrum

In the good old days of monoliths, a single database transaction could span multiple operations, ensuring atomicity (all or nothing) through a two-phase commit (2PC) protocol. In a microservices world, 2PC is largely a non-starter. It introduces tight coupling, blocks resources for extended periods, and is notoriously difficult to scale and recover from failures in a distributed environment. Imagine a payment service waiting for an inventory service, which is waiting for a shipping service – a recipe for deadlocks and cascading failures at 100 million requests per second. We need a different approach.

Enter the Saga Pattern: Choreography Style

The Saga Pattern is a design pattern that manages distributed transactions by breaking them down into a sequence of local, atomic transactions. Each local transaction updates data within a single service and publishes an event. This event then triggers the next local transaction in another service. If any local transaction fails, the saga executes a series of compensating transactions to undo the changes made by previous successful transactions.

There are two main styles of Saga: Orchestration and Choreography. Today, we focus on Choreography.

In a Choreography-based Saga:

  • No Central Coordinator: Each service involved in the saga is a participant.

  • Event-Driven Communication: Services communicate by publishing and subscribing to events.

  • Loose Coupling: Services are unaware of the overall saga logic; they only react to events relevant to them and publish events for others.

This style is particularly powerful for systems demanding extreme scalability and resilience.

A Real-World Voyage: E-commerce Order Fulfillment

Let's illustrate this with a classic example: an e-commerce order fulfillment process.
Imagine a customer places an order. This isn't just one step; it's a sequence:

  1. Create Order: The OrderService creates the order in its database.

  2. Process Payment: The PaymentService processes the payment.

  3. Reserve Inventory: The InventoryService deducts items from stock.

  4. Schedule Shipping: The ShippingService arranges for delivery.

Each of these steps is handled by a different microservice, owning its data.

The Choreographed Flow:

  1. A user places an order via the OrderService.

  2. The OrderService saves the order with status PENDING_PAYMENT and publishes an OrderCreatedEvent to a message broker (e.g., Kafka).

  3. The PaymentService consumes OrderCreatedEvent. It processes the payment.

  • If successful, it publishes PaymentProcessedEvent.

  • If failed, it publishes PaymentFailedEvent.

  1. The InventoryService consumes PaymentProcessedEvent. It attempts to reserve items.

  • If successful, it publishes InventoryReservedEvent.

  • If failed, it publishes InventoryFailedEvent.

  1. The ShippingService consumes InventoryReservedEvent. It schedules shipping.

  • If successful, it publishes ShippingScheduledEvent.

  • If failed, it publishes ShippingFailedEvent.

The Compensation Dance:

Keep going with the full lesson

The rest of this lesson β€” plus its implementation guide, runnable scripts and source code β€” is included with the course or an All Access plan. Create a free account to start the free lessons in every course.

Already a member? Sign in