How do I manage distributed transactions?
But here’s a better question:
Do you really need a Saga or are you just working around a missing feature?
What the Saga Pattern Promises
At a high level, Sagas break a large transaction into smaller, local ones. If something goes wrong mid-way, you call compensating operations to undo the earlier steps. Simple idea, right? Not quite. In practice, Sagas introduce serious complexity:- You need to define undo logic for every operation.
- Undo may not even be possible if other processes have already acted on the data.
- Services are left in “doubt” until the saga completes which complicates monitoring, reporting, and testing. Most of the time, a service never even knows if it will be compensated for or not, making reporting very hard.
- Failures in the undo steps? Now you need retries for your compensations, too.
By the time you are done wiring up your Saga, you have written half an orchestration engine and double the update logic that you would normally need for each service.
What if You Could Just… Roll Back?
The whole reason we reach for Sagas is because we can’t roll back across services, right? But what if you could? That’s what the Transactional Call pattern enables: a true atomic, all-or-nothing operation that spans multiple microservices with rollback support built-in.How Transactional Call Works
With Atomikos and XA transactions:- MS1 starts a new transaction.
- It calls MS2 and MS3, passing a transaction context.
- Each service performs its work
tentatively, nothing is committed yet. - If all calls succeed, MS1 commits the transaction, and everything becomes final.
- If anything fails, rollback is automatic – everywhere.
No compensating logic. No cleanup jobs. No state machines. Just consistency.
When to Use What
| Situation | Transactional Call | Saga |
|---|---|---|
| Internal services only | ||
| Need strong consistency | ||
| Operations are naturally undoable | ||
| Avoid custom rollback logic |
Summary
- Sagas are useful only when true rollback isn’t possible.
- Most of the time, you can get rollback, with a Transactional Call.
- Atomikos makes this easy in Spring Boot, JDBC, JMS, and beyond.
- Don’t write compensation logic if you don’t have to.

Add a comment