I have 2 microservices S1
and S2
. S1
invokes S2
to update a data and then S1
inserts another data,But let's consider S1
fails,Then we need to rollback the data updated by S2
or else we'll be in inconsistent state.
I also gone through Saga patterns.will it satisfy this inconsistency
Can anyone suggest any better solutions for this?
Distributed transactions are problematic for most circumstances and they are bad for services
- Service Boundary – service boundary is a trust boundary. Atomic
transactions require holding locks and holding them on behalf of
foreign service is opening a security hole (makes it much easier to
do a denial of service attack) You cannot assume atomicity between
two different entities or resources. Esp. when these resources belong
to different businesses.
- Transactions introduce tight coupling both temporal and operational
- Transactions hinder scalability – It isn’t that you can’t scale
but it is much harder
Sagas (which, by the way, do not necessitate orchestration) emerged as a solution for coordination because they allow services to be more flexible - and are in fact closer to how real life work. Another pattern you can combine with Sagas to help with delaying effects can be reservation.
Another option you have might be reconsidering how you partitioned your services. It might be that the service boundaries you have now are not correct and a redesign will contain the needed transaction into one service
I think Saga pattern (Orchestration) enables an application to maintain data consistency across multiple services without using distributed transactions.
This solution has the following drawbacks:
The programming model is more complex. For example, a developer must design compensating transactions that explicitly undo changes made earlier in a saga.
There are also the following issues to address:
In order to be reliable, a service must atomically update its database and publish an event. It cannot use the traditional mechanism of a distributed transaction that spans the database and the message broker.
If both S1
and S2
are "under your control", than you are much better off designing them in a way that doesn't require distributed transactions. After all, microservices are supposed to be independent services. They are obviously not independent, if they must share a transaction.
If only one of those is under your control and the other one isn't, then the simplest way is to order the calls in a way that won't require a rollback on the service that is not under your control. If you are lucky, you might even order calls in a way that don't require any rollbacks, not even in your service. Remember, you don't have to solve distributed transactions in general, just solve the actual use-case you face!