The Saga pattern is a distributed transactional pattern used in microservices architecture to maintain data consistency across multiple services. It helps manage long-running transactions involving multiple services by breaking them down into smaller, more manageable work units.
There is a famous Database per Service pattern in the Microservice world. Under this paradigm, each service maintains its own dedicated database. Some business transactions, however, span multiple services so we need a mechanism to implement transactions that span through services. Take, for instance, the scenario of placing an online order, which involves actions like inventory verification and item reservation till payment completion. Since services such as Orders, Inventory, and Payment operate on separate databases, the application cannot simply use a local ACID transaction.
2 Phase Commit Protocol is one of the options being used for ensuring transactions across services. However, it has several challenges:
- Blocking can occur if any participant fails to respond during the prepare phase.
- A Single Point of Failure may arise if the coordinator fails, leading to the potential blockage or failure of the entire transaction.
- It does not effectively scale for a significant number of participants.
- Each microservice has its own database, enabling it to manage local transactions atomically with strong consistency.
- Saga pattern groups these local transactions and sequentially executes them one by one. Each local transaction updates its database and then publishes an event to trigger the next local transaction.
- In case of a failure in one of the steps, the saga pattern initiates rollback transactions. These rollback transactions comprise a series of compensating actions that undo the changes made by previous microservices, thereby restoring data consistency.
1. Choreography Saga Model:
Happy flow when a user places an order:
- The user sends an Order Request
- Order Service initiates the creation of an order history entry in its Orders database, setting the order status to "Pending"
- Order Service then publishes a message/event onto the Inventory_Request topic, signaling the next service in the chain.
- The Inventory Service then receives the event from the Inventory_Request topic along with relevant metadata.
- Inventory Service then proceeds to update its Inventory table accordingly. It verifies if it has the available stock. If available, reserve it till the payment is successful.
- Subsequently, it publishes another event onto the Payment_Request topic for the subsequent service to process.
- The Payment Service then receives the event from the Payment_Request topic along with relevant metadata.
- Upon receipt of the event from the Payment_Request topic, the Payment Service executes its payment processing actions and updates its Payment database accordingly.
- If the payment is successful, the Payment Service publishes a success event onto the Payment_Request_Success topic.
- The Inventory Service, monitoring the Payment_Request_Success topic, takes further action on its Inventory table based on the success event.
- Inventory Service then publishes a success message onto the Inventory_Request_Success topic.
- Finally, the Order Service, upon detecting the success message on the Inventory_Request_Success topic, updates the order status from "Pending" to "Success", thus marking the order as successfully processed.
An error encountered when a user places an order:
- The user sends an Order Request (Note: First 7 steps are the same as happy case)
- Order Service initiates the creation of an order history entry in its Orders database, setting the order status to "Pending"
- Order Service then publishes a message/event onto the Inventory_Request topic, signaling the next service in the chain.
- The Inventory Service then receives the event from the Inventory_Request topic along with relevant metadata.
- Inventory Service then proceeds to update its Inventory table accordingly. It verifies if it has the available stock. If available, reserve it till the payment is successful.
- Subsequently, it publishes another event onto the Payment_Request topic for the subsequent service to process.
- The Payment Service then receives the event from the Payment_Request topic along with relevant metadata.
- Say an error encountered while processing the payment, the Payment Service will update its database for the failed payment transaction.
- In the event of a payment failure, the Payment Service logs a failed event onto the Payment_Request_Failed topic.
- Subsequently, the Inventory Service retrieves this event from the Payment_Request_Failed topic and undertakes compensatory action, reverting the inventory count to its previous state, updated during Step 5.
- After executing the compensation action, the Inventory Service publishes a failed message onto the Inventory_Request_Failed topic.
- The Order Service, upon detecting the failed message on the Inventory_Request_Failed topic, updates the order status from "Pending" to "Failed", thereby marking the order as unsuccessful.
Comments
Post a Comment