Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rollback MicroServices

I have doubt related to MicroServices. Suppose there are 5 Micro-Services, lets say M1, M2, M3, M3, M4 and M5. There are 4 databases which are connected/accessed by 4 micro-services. For example, M2 connected to MySQL, M3 connected to Cassandra, M4 connected to MongoDB and M5 connected to Oracle.

Now

Step-1: M1 making a call to M2 to update some user data in MySQL and it updated successfully then finally it got success response from M2

Step-2: M1 making a call to M3 to update some data in Cassandra and it updated successfully then finally it got success response from M3

Step-3: M1 making a call to M4 to update some data in MongoDB and it failed due to some DB server problem or any other problem.

Here my requirement is, I want to rollback DB changes that happened to previous micro-services(M2 and M3)

What should we need to do to achieve this kind of rollback scenario?

like image 780
Sat Avatar asked Oct 01 '19 05:10

Sat


People also ask

How do I roll back my saga pattern?

Rollback of Saga Pattern So when it failed to one step, The Saga invokes a set of compensating transactions to rollback the inventory operations, cancel the payment and the order, and return the data for each microservice back to a consistent state.

Can we use distributed transactions for microservices?

Typical examples are transactions that include one or more databases or a database and a message broker. These transactions are called global or distributed transactions. They enable you to apply the ACID principle to multiple systems. Unfortunately, they are not a good fit for a microservice architecture.

How do I rollback a spring boot transaction?

Use @Transactional(rollbackFor={CustomCheckedException. class}) if you need rollback on some checked exception. It is also because @Transactional works by proxying your object. In example above a() will call X.b() not a enhanced "spring proxy" method b() so there will be no transaction.


2 Answers

This is a typical case of distributed transaction. Regardless of the fact that you use separate technology for your database or the same on different server you perform an operation which is transactional. In order to handle a rollback on that type of transaction you can not relay on the database technology mechanism for transactions and rollbacks. You have to do it on your own.

Saga Pattern

Common solution for distributed transaction scenarios in micro-service architecture is the Saga pattern. Distributed sagas is a pattern for managing failures in scenarios as the one that you have described.

Saga are created based on business process for example "Buy a Product in online shop". This process can involve multiple actions on multiple micro-services. Saga will control and manage this process execution and if one of the steps fail it will trigger actions to revert the actions done before the failing action.

There are multiple ways to implement sagas. It depends on your architecture and the way your micro-services communicate with each other. Do you use Commands and/or Events?


Example

"Buy a Product in online shop" business process. Lets say this business process has 3 simple steps done by 3 different micro-services:

  • Action 1 - Reserve Product in products-inventory-micro-service
  • Action 2 - Validate payment in payment-micro-service
  • Action 3 - Order a product in orders-micro-service

Using Events:

You can publish events to perform some action(or actions) and if one of the action fails you can publish a revert(or delete) event for that event. For the above business process lets say the 1. Action succeeded and the 2. Action failed. In this case in order to rollback the 1. Action you would publish an event like "RemoveReservationFromProduct" in order to remove the reservation and revert the state back to the state as it was before the transaction for that Business process started. This event would be picked up by a event handler which would go and revert that state in your database. Since it is an event you can implement retry mechanism for failures or just reapply it later if there is some bug in the code.

Using commands:

If you have direct calls to your micro-services as commands using some kind of rest api you could run some delete or update endpoints to revert the changes that you have done. For the above business process lets say the 1. Action succeeded and the 2. Action failed. In this case in order to rollback the 1. Action you would call the delete api to delete the reservation for a particular product in order to remove the reservation and revert the state back to the state as it was before the transaction for that Business process started.

You can take a look at this example how to implement the Saga pattern.

like image 67
xargs Avatar answered Jan 04 '23 20:01

xargs


From what I understand, a Saga is what you are looking for. The idea is to provide for every state altering operation an undo-operation, that has to be called if things went bad down stream.

like image 33
sschrass Avatar answered Jan 04 '23 19:01

sschrass