we have microservice
architecture where for most part each microservice
is independent. But for some legacy reasons, there is a situation where we have to call another microservice
from within another.
eg: the following method is part of Legal Service
@Autowired
public ServiceManager UserServiceManager;
public void updateUserLegalData(){
//do db update of Legal info for the user
userServiveManager.setAcceptedLegal(true);
}
There are two db transactions
going on above. one is updating legalService db and other is updating UserService db. please NOTE userService is a microservice
running on a separate VM.
we are seeing situations where legal Service db is updated but call to userService is failing (Internal server error
). so this leaves the application in an inconsistent state. How can we fix this in a recommended way?
Thanks
This situation can be handled only with JTA global/distributed transactions. JTA is part of Java EE standard and can have various implementors. Atomikos is often tool of choice.
Here is good writeup from Dave Syer (Spring ecosystem contributor). It contain also working examples. It's little bit outdated, but still relevant. You can apply some more modern Spring abstractions on top of his examples.
I created few GitHub examples of JTA transactions for my book. Notice that there are errors simulated and transaction is spread across JMS and JDBC datasources.
But also bear in mind that JTA transactions across various data sources are slow, because of 2-phased commit algorithm involved. So often people try to avoid them and rather deal with inconsistencies somehow pragmatically.