Pattern: Saga
pattern transaction management sagas service collaboration implementing commandsWant to learn more about this pattern?
Take a look at my self-paced, online bootcamp that teaches you how to use the Saga, API Composition, and CQRS patterns to design operations that span multiple services.
The regular price is $395/person but use coupon OFFEFKCW to sign up for $95 (valid until Sept 30th, 2025)
      
  Context
You have applied the Database per Service pattern. Each service has its own database. Some business transactions, however, span multiple service so you need a mechanism to implement transactions that span services. For example, let’s imagine that you are building an e-commerce store where customers have a credit limit. The application must ensure that a new order will not exceed the customer’s credit limit. Since Orders and Customers are in different databases owned by different services the application cannot simply use a local ACID transaction.
Problem
How to implement transactions that span services?
Forces
- 2PC is not an option
 
Solution
Implement each business transaction that spans multiple services as a saga. A saga is a sequence of local transactions. Each local transaction updates the database and publishes a message or event to trigger the next local transaction in the saga. If a local transaction fails because it violates a business rule then the saga executes a series of compensating transactions that undo the changes that were made by the preceding local transactions.

There are two ways of coordination sagas:
- Choreography - each local transaction publishes domain events that trigger local transactions in other services
 - Orchestration - an orchestrator (object) tells the participants what local transactions to execute
 
Example: Choreography-based saga

An e-commerce application that uses this approach would create an order using a choreography-based saga that consists of the following steps:
- The 
Order Servicereceives thePOST /ordersrequest and creates anOrderin aPENDINGstate - It then emits an 
Order Createdevent - The 
Customer Service’s event handler attempts to reserve credit - It then emits an event indicating the outcome
 - The 
OrderService’s event handler either approves or rejects theOrder 
Take a tour of an example saga
Example: Orchestration-based saga

An e-commerce application that uses this approach would create an order using an orchestration-based saga that consists of the following steps:
- The 
Order Servicereceives thePOST /ordersrequest and creates theCreate Ordersaga orchestrator - The saga orchestrator creates an 
Orderin thePENDINGstate - It then sends a 
Reserve Creditcommand to theCustomer Service - The 
Customer Serviceattempts to reserve credit - It then sends back a reply message indicating the outcome
 - The saga orchestrator either approves or rejects the 
Order 
Take a tour of an example saga
Resulting context
This pattern has the following benefits:
- It enables an application to maintain data consistency across multiple services without using distributed transactions
 
This solution has the following drawbacks:
- 
    
Lack of automatic rollback - a developer must design compensating transactions that explicitly undo changes made earlier in a saga rather than relying on the automatic rollback feature of ACID transactions
 - 
    
Lack of isolation (the “I” in ACID) - the lack of isolation means that there’s risk that the concurrent execution of multiple sagas and transactions can use data anomalies. consequently, a saga developer must typical use countermeasures, which are design techniques that implement isolation. Moreover, careful analysis is needed to select and correctly implement the countermeasures. See Chapter 4/section 4.3 of my book Microservices Patterns for more information.
 
There are also the following issues to address:
- 
    
In order to be reliable, a service must atomically update its database and publish a message/event. It cannot use the traditional mechanism of a distributed transaction that spans the database and the message broker. Instead, it must use one of the patterns listed below.
 - 
    
A client that initiates the saga, which an asynchronous flow, using a synchronous request (e.g. HTTP
POST /orders) needs to be able to determine its outcome. There are several options, each with different trade-offs:- The service sends back a response once the saga completes, e.g. once it receives an 
OrderApprovedorOrderRejectedevent. - The service sends back a response (e.g. containing the 
orderID) after initiating the saga and the client periodically polls (e.g.GET /orders/{orderID}) to determine the outcome - The service sends back a response (e.g. containing the 
orderID) after initiating the saga, and then sends an event (e.g. websocket, web hook, etc) to the client once the saga completes. 
 - The service sends back a response once the saga completes, e.g. once it receives an 
 
Related patterns
- The Database per Service pattern creates the need for this pattern
 - The following patterns are ways to atomically update state and publish messages/events:
 - A choreography-based saga can publish events using Aggregates and Domain Events
 - The Command-side replica is an alternative pattern, which can replace saga step that query data
 
Learn more
- My book Microservices patterns describes this pattern in a lot more detail. The book’s example application implements orchestration-based sagas using the Eventuate Tram Sagas framework
 - Take a look at my self-paced, online bootcamp that teaches you how to use the Saga, API Composition, and CQRS patterns to design operations that span multiple services.
 - Read these articles about the Saga pattern
 - My presentations on sagas and asynchronous microservices.
 
Example code
The following examples implement the customers and orders example in different ways:
- Choreography-based saga where the services publish domain events using the Eventuate Tram framework
 - Orchestration-based saga where the 
Order Serviceuses a saga orchestrator implemented using the Eventuate Tram Sagas framework - Choreography and event sourcing-based saga where the services publish domain events using the Eventuate event sourcing framework
 
      
      
    Premium content now available for paid subscribers at 
  
      
  
      
  