80/20 Of The Week … Spring Transactions (JPA, JTA, …)
How transactions usually go is:
- begin transaction
- run a few queries
- commit or rollback
And that is fine when we are talking about one database.
But in some applications the interesting question becomes who actually manages that transaction? The basic idea is that transactions group multiple operations into one unit of work. For example:
- create order
- decrease product stock
- save payment record
If everything succeeds, we commit and if something fails, we rollback.
- What Spring adds
In Spring, we usually do not manually write begin/commit/rollback everywhere.
We write something like:
@Transactional
and Spring handles the transaction boundary around the method. So the service method becomes the unit of work.
What actually manages it is the annotation@Transactionaland behind it we have a transaction manager.
For example:
JpaTransactionManagerDataSourceTransactionManagerJtaTransactionManager
Why do we have multiple options here? Weeelll if you use one JPA persistence unit / one database, JpaTransactionManager is usually enough.
If you use plain JDBC, DataSourceTransactionManager is usually the common one.
Buuut if you need one transaction across multiple transactional resources, JtaTransactionManager is the one that enters the conversation.
- Distributed transactions
Imagine this service method:
createOrder()
Inside it we:
- insert order
- reduce stock
- create payment record
If the stock update fails, we do not want the order to remain half-created.
That is what @Transactional protects us from.
Either all DB changes succeed… or all of them rollback.
Now imagine the operation touches:
- database A
- database B
- JMS/message queue
A normal local transaction manager can manage one resource well. But it cannot magically coordinate multiple independent transactional systems.
That is why JTA/XA exists. It is meant for transactions that span multiple resources.
This does not mean:
“just put @Transactional and everything is solved.”
If you call another microservice, send an email, call Stripe, or publish an event outside the same transaction…
Spring cannot simply rollback the whole world.
That is where patterns like Outbox, Saga, idempotency, and retries become important.
3)Main takeaway
@Transactional is not magic.
It is a clean way to define transaction boundaries.
The important part is knowing what is behind it:
one database usually means local transaction management
multiple transactional resources may require JTA/XA
distributed systems often need additional patterns beyond transactions
#Java #SpringBoot #SpringFramework #Databases #Transactions #JPA #JTA #Backend
