One of the most common problem that a microservice architecture is facing is performing a transaction across multiple services.
A distributed architecture is based on a number of small components, functions or services, that works independently and update their corresponding data sources with no concerns for other components activity.
As a result, the data committed to the data store in a distributed transaction may became in-consistent since some components activities may completes successfully while other fails.
The solution to this problem is by implementing the Saga design pattern as described in the link from below:
A saga is a sequence of transactions that updates each service and publishes a message or event to trigger the next transaction step. If a step fails, the saga executes compensating transactions that counteract the preceding transactions.
There are two common saga implementation approaches, choreography and orchestration.
Choreography
Choreography is a way to coordinate sagas where participants exchange events without a centralized point of control. With choreography, each local transaction publishes domain events that trigger local transactions in other services.
Orchestration
Orchestration is a way to coordinate sagas where a centralized controller tells the saga participants what local transactions to execute.
The saga orchestrator handles all the transactions and tells the participants which operation to perform based on events.
The orchestrator executes saga requests, stores and interprets the states of each task, and handles failure recovery with compensating transactions.
Sample code
Atomic transactions with the Service Bus
This project is using the service bus queues and a Saga choreography pattern to create a framework that takes care of committing or rolling back distributed transactions.
Each transaction it is enrolled into a workflow (topology) that specifies what is the next step of execution to follow for either a success or a failure result.
If a transaction fails, the message it is forwarded from the dead letter queue to the Cancel queue.
2. Saga orchestration serverless
This is an orchestration saga executed with Azure Durable functions and Azure Event Hub for sending the events between functions.
The design is storing the failed events into a Cosmos database and sends compensatory events to trigger compensatory transactions: in the image from below, event 11 triggers the orchestrator to send event 13 and rollback the "Transfer" transaction after the "Receipt" transaction failed.
Coming next...
In the next article I will describe a framework I have created using the Azure durable functions to commit and rollback automatically the enrolled transactions processed either in sequence or in parallel.
Comments