Reputation: 2851
I have the need to insert 2 different entities into 2 different tables, using the same transaction. If the second insert fails, the first one should be rolled back.
Is there any way of doing this nicely?
Pseudo code:
start tx
repo1.save(myEntity);
repo2.save(anotherEntity);
try commit
I know you can leverage @Transactioal
but only on method level?
Upvotes: 15
Views: 12233
Reputation: 5407
you need check that you don't have set autocommit = false.
wrap save operations into one service method and make it @Transactional
. But if you use save()
custom method check that save in not marked as @Transactional
with propagation level required_new or nested. If you need you can use REQUIRES_NEW
for saving service method to make this service method transaction independent of other transactions.
also you can wrap in with TransactionTemplate.
@Autowired
private TransactionTemplate transactionTemplate;
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
public void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
repo1.save(myEntity);
repo2.save(anotherEntity);
});
Upvotes: 12
Reputation: 4224
Steps to follow:
Upvotes: -3
Reputation: 40036
It is usually a wrong idea to have @Transactional
declared around repository methods.
Repositories are only for you to access domain entities. Business logic normally involves multiple domain entities and collaborations between them.
In your architecture you should have a layer to compose business logic. This usually corresponds to a service exposed to external.
This is usually the place you should have your transaction boundary set on. Usually it is a Controller, or a Service method.
Upvotes: 11