Skip to main content

Saga Pattern

Introduction​

Since decades, Computer Science is dealing with transactions. ACID principles form the ground of our traditional database systems. The core of transactions is to process a set of operations together in an all-or-nothing scenario. Especially in monolithic applications, transactions are used to keep data consistent all the time - although multiple rows or tables are affected.

Transactional consistency is important and required by a lot of business scenarios. Transactions are widely used and accepted and have proven their practical relevance over time being. Traditional approaches to use transactions in a distributed system turn out to not work. Therefore other patterns have been established over time, like avoiding transactions by design or Saga.

The Saga architecture pattern provides transaction management by using a sequence of local transactions. Saga participants perform those local transactions as a unit of work. The participants are responsible for rolling back the operations by applying compensational actions.

The Saga pattern guarantees that either all operations complete successfully or the corresponding compensations are run to (semantically) undo the previous work.

Requests can abort and must be idempotent (retriable). Compensating Requests semantically undo the effect of a request. They cannot abort and must be idempotent and commutative.

⚠warning

One major problem of Saga is the lack of isolation. This means, that it is guaranteed to obtain a consistent state only at the end of the Saga, but not in any intermediate step.

Saga Pattern Support​

For Domain Services based on Java Spring Boot Stack 2.0, IBM Industry Solutions Workbench provides various capabilities, to support the development of transactional use cases.

The extension is available for the following stacks:

  • Java Spring Boot Stack 2.0.0 and later

How it works​

If the Saga Pattern support extension is enabled, the Solution Designer UI offers additional modelling capabilities.

Domain and Integration Services can now be created with a Saga Pattern role. Services with the Orchestrator role are representing the starting point of a Saga. Saga Participant services contain the actual execution logic of the steps within a Saga and are associated to an Orchestrator. When a Saga is triggered, all of the associated participants are executed by the orchestrator eihter in parallel or sequentially. To learn more about modelling a Saga, please check Modelling of Saga Pattern role in Services.

Dependending on what has been modelled in the Solution Designer UI, you will get auto-generated stub files for your orchestrators and participants. There, you will only have to implement the execution, completion and compensation logic for your use case, while a secure connection to the lra-coordinator is established out of the box. This part will be automatically provided in the SDK, not requiring any custom implementation. To learn more about implementating a Saga, please check Implement Saga pattern.

A Saga can also spawn across several microservices. Therefore, API Operations can be marked as a Saga participant as well. It is recommended, that those API operations will again trigger the execution of an Orchestrator. When doing this, the Saga context will automatically be applied. To learn more about this, please check Modelling of API Operations and Implementing Saga across multiple services.

💡tip

For your compensation logic, you need to know what has been changed in the related context of the Saga. In most cases, the only input you will get there is the Long-Running-Action-Id. When designing the use case, it is often helpful to consider storing those Long-Running-Action-Ids to make use of them during compensation.

Technology​

The Saga Pattern support extension in IBM Industry Solutions Workbench makes use of

Deployment​

It is recommended to deploy Saga use cases through an Application Composition project. To share the Saga context between all the services in the Application, the services must be bound to the same lra-coordinator.

Deployment with Oracle MicroTx as lra-coordinator​

When using Oracle MicroTx, the lra-coordinator must be installed into the OpenShift Cluster separately. The installation instructions can be found within the official Oracle MicroTX documentation. In this case, the binding to the lra-coordinator must be done via custom configuration. The information, which lra-coordinator is used, is defined within a secret (naming convention k5-appAcronym-lra-coordinator-binding). This secret needs to be created and filled with proper values by the lra-coordinator component. In case of the Oracle MicroTx, these values can be used:

lra.coordinatorUrl: <url-of-lra-coordinator>
lra.coordinator-context-path: api/v1/lra-coordinator

Saga Application with Oracle MicroTx

Deployment with jboss Narayana as lra-coordinator​

When using jboss Narayana, the lra-coordinator must be part of the Application Composition project. In this case, the binding to the lra-coordinator is automatically set up correctly and does not require any custom configuration.

Saga Application with jboss Narayaa

💡tip

According to best practices, the Saga should not leave the boundaries of an Application Composition project.

Custom configuration​

When Saga services are used together with a lra-coordinator within an Application Composition project, all required configurations are set up correctly by default. However, in some cases it might be necessary to apply custom configurations. Changing the default settings is easily possible through the Solution Designer.

Disable security​

For all Saga services, the communication with the lra-coordinator, is secured by default. To disable security in your project, which is implementing the Saga, you have to execute the following steps:

  • Open action Configure Component in your Application Composition project
  • Add a custom configuration to your component:
    # Feature flags
    feature:
    secureNarayana: false
  • Save your custom configuration and commit your changes
ℹī¸note

To get this setup running, please ensure, that the used lra-coordinator has disabled security as well.

Use a different lra-coordinator service​

By default, a Saga service in an Application Composition project always uses the lra-coordinator, which is also deployed through the same application. The information, which lra-coordinator is used, is defined within a secret (naming convention k5-appAcronym-lra-coordinator-binding). This secret needs to be created and filled with proper values by the lra-coordinator component.

Configuring a different lra-coordinator for a component can be done by the following steps:

  • Create a new secret with a custom name
  • Set the correct values to the secret (key/value pair):
    lra.coordinatorUrl: <url-of-lra-coordinator>
    lra.coordinator-context-path: <context-path-of-lra-coordinator>
  • Open action Configure Component of your Saga service in your Application Composition project
  • Add a custom configuration to your component:
    # Saga
    camel:
    lra:
    coordinatorBindingSecretName: "<your-new-secret-name>"
  • Save your custom configuration and commit your changes

Modeling Saga Orchestrator​

For Service Projects of type Java Spring Boot where the extension Saga Pattern Support is enabled, each Domain Service can be either be marked as a Saga Orchestrator or as Saga Participant during creation of a service. These basic settings can be changed at any time in the service overview.

Saga Orchestrator services are representing the starting point of a Saga. They are responsible to trigger the execution of the participants in the correct saga context.

💡tip

If your Saga is spread across multiple microservices, every microservice needs to have at least one Orchestrator service in it.

For a service marked as a Saga Orchestrator the following input fields are needed:

  • Association with one participant: If set to true an orchestrator with exactly one participant will be generated automatically.
  • On Compensate Method: If set to true automatically an onCompensate method will be generated.
  • On Complete Method: If set to true automatically an onComplete method will be generated.
  • Propagation Level: required, requires_new, mandatory, supports, not_supported, never
  • Completion mode: auto or manual
  • Execution mode (optional): parallel (default), or sequential
  • Participants: You can associate participants by using the Add action. All services of the project that are marked as Saga Participant are shown and can be associated. To remove the association you can either deselect or use the row action Remove.

This section lists participants that depend on this service as their orchestrator, helping to clarify its coordinating role within the saga.

Modeling Saga Participant​

Saga Participant services contain the actual execution logic of the steps within a Saga and are associated to an Orchestrator.

For a service marked as a Saga Participant the following input fields are needed:

  • On Compensate Method: If set to true automatically an onCompensate method will be generated.
  • On Complete Method: If set to true automatically an onComplete method will be generated.
  • Propagation Level: required, requires_new, mandatory, supports, not_supported, never
  • Completion mode: auto or manual
  • Options Expressions: Key-value pair used to define additional context for the Saga. They are sent by the coordinator, when compensating or completing. The value can be expressed in the camel expression language. For more information see also Apache Camel Saga EIP Options
ℹī¸note

Please consider, that Saga Participants need to have the same input entity modeled as the Saga Orchestrators to which they are associated. The input will automatically be passed from the orchestrator to its participants.

⚠warning

Please note that changing the "Saga Pattern Role" field afterwards can break already implemented code!

This section shows orchestrators that utilize this service as a participant, highlighting its role and dependencies within the saga.

How-To: Import Asset and use it to enable SAGA functionality.