Skip to main content

Saga pattern

Context and problem

In context of a microservice system, it's very likely that you have applied database per service pattern. Some transactions, however, span multiple services and we need a mechanism to implement such transactions. Since each service owns different database, a local ACID transaction cannot simply be applied.

Conceptual overview

The saga pattern provides transaction management using a sequence of local transactions. Each local transaction updates its own database and publishes a message or event to trigger the next transaction in the saga. If a local transaction fails, the saga must execute compensating transactions that undo changes that were made by preceding local transactions. This example from Microsoft illustrates the pattern saga-example

Choreography

Choreography is a way to coordinate sagas without a centralized point of control. Each service is aware of the next saga participant after updating its own database. Here's an example of choreography saga taken from Microsoft saga-choreography

Orchestration

Orchestration is a way to coordinate sagas with a centralized point of control. An orchestrator (object) tells the participant what local transactions to execute. Here's an example of orchestration saga taken from Microsoft saga-choreography

Code details

Saga pattern can be checked in order service. In this example application, orchestration was chosen to implement the saga pattern. The orchestrator object is a Spring state machine which leverages traditional finite-state machine concepts in computer science. This diagram illustrates states, state transitions and actions of the state machine.

state-machine States that are decorated with double circles are start and end states. The arrow illustrate the state transition. There's an action, that will be fired, when the state is changed.

Here is the state machine configuration

state machine configuration

And here is the definition for state machine actions

state machine actions

Compensating logic

An example for compensating logic can be found in ValidateOrderFailedAction.java, where we want to send a message to payment service and revert the payment that user has already checked out