Skip to content

How To Ensure Data Integrity With The Saga Pattern

Reading Time: 2 minutes

Microservices architecture offers the advantage of breaking down an application into small, decoupled services, with each service owning the data it manages. However, a challenge arises when generating a transaction involving multiple services. To address this issue, the SAGA pattern is employed.

Purpose of the SAGA Pattern

The SAGA pattern emerges from the need to have transactions closely resembling ACID properties in microservices architectures.

What is an ACID Transaction?

An ACID transaction possesses the following properties:

Atomicity: The transaction comprises operations that are either all executed or none at all.

Consistency: The transaction transforms data from one consistent state to another.

Isolation: Concurrent transactions operating on the same data do not interfere with each other.

Durability: Once committed, the transaction’s state persists despite system failures.

In microservices architecture, however, achieving full ACID transactions is challenging. Isolation is compromised due to separate databases for each service. This makes it difficult to ensure isolation since it requires the availability of all involved services, which is hard to guarantee in a distributed system like microservices. Thus, applications must implement countermeasures to prevent or mitigate anomalies resulting from the lack of isolation.

ACD Transactions

Microservices-based transactions typically exhibit ACD properties (Atomicity, Consistency, Durability). They lack the isolation feature of traditional ACID transactions. Consequently, applications must employ design techniques to prevent or minimize concurrency anomalies stemming from isolation deficiencies.

The Essence of the SAGA Pattern

A saga is an operation comprising several smaller steps. Each step represents a specific task managed by one of the microservices—referred to as the Principal Action. Additionally, each step has a Compensating Action, which performs operations to undo the principal action in case the current step or any subsequent step fails.

Thus, a saga coordinates and executes all principal actions of its steps. In case of failure, it executes the necessary compensating actions to restore data consistency.

Example of a Saga

SConsider an online article purchasing system. When a user places an order, the following steps must occur:

StepPrincipal ActionCompensating Action
1 – Create a purchaseRegister the purchase with a pending statusSet purchase status as canceled
2 – Process paymentValidate payment and reserve the payment amountCancel amount reserved for payment
3 – UpdateInventoryCheck stock and deduct the purchased amountRevert stock subtracted

Saga steps

SAGA Pattern Implementation

There are two ways to implement the saga pattern: using choreography or orchestration.

Choreography Implementation

In this approach, each service handles a step and notifies the next step to execute its principal or compensating action. It also notifies the previous step to execute its compensating action if needed.

Saga pattern  implemented with  processed Choreography
Saga processed successfully with choreography

In the following image, you can see how the SAGA would react if an error occurs in the inventory stage and how each step is compensated until the order is canceled and the user is informed of the outcome.

Saga pattern - Compensation implemented with  processed Choreography
Saga compensated in choreography because fail the inventory steap

Orchestration Implementation

In this setup, an orchestrator service controls the saga’s execution and compensating actions for rollback. The orchestrator is often designed as a state machine, where each state represents a saga step and contains the principal and compensating actions.

Saga pattern  implemented with  processed Orchestrator
Saga processed with orchestrator

This is the sequence of compensation calls in case the inventory step fails.

Saga pattern - Compensation implemented with Orchestrator
Saga compensated in orchestration because fail the inventory step

Conclusion

Choreography’s advantage is decentralized management, but tracking errors can be difficult. It’s best for small and stable sagas. Orchestrator, though it has a single point of failure, offers encapsulation, easier testing, synchronous sagas, and simplified transaction isolation policies. It’s suitable for complex or multiple sagas, with consideration for orchestrator scaling.

Referencias

https://microservices.io/patterns/data/saga.html

https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/saga/saga

Published inArchitecture

Be First to Comment

Leave a Reply

Discover more from Samurai Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading