I have a method that does a bunch of things; amongst them doing a number of inserts and updates.
It's declared thusly:
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false) public int saveAll() { //do stuff; }
It works exactly as it is supposed to and I have no problems with it. There are situations however when I want to force the rollback in spite of there not being an exception... at the moment, I'm forcing an exception when I encounter the right conditions, but it's ugly and I don't like it.
Can I actively call the rollback somehow?
The exception calls it... I'm thinking maybe I can too.
RollbackException exception is thrown when the transaction has been marked for rollback only or the transaction has been rolled back instead of committed. This is a local exception thrown by methods in the UserTransaction , Transaction , and TransactionManager interfaces.
@Transactional only rolls back transactions for unchecked exceptions. For checked exceptions and their subclasses, it commits data. So although an exception is raised here, because it's a checked exception, Spring ignores it and commits the data to the database, making the system inconsistent.
The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.
In Spring Transactions, you use TransactionStatus.setRollbackOnly()
.
The problem you have here is that you're using @Transactional
to demarcate your transactions. This has the benefit of being non-invasive, but it also means that if you want to manually interact with the transaction context, you can't.
If you want tight control of your transaction status, you have to use programmatic transactions rather than declarative annotations. This means using Spring's TransactionTemplate, or use its PlatformTransactionManager directly. See section 9.6 of the Spring reference manual.
With TransactionTemplate
, you provide a callback object which implements TransactionCallback
, and the code in this callback has access to the TransactionStatus
objects.
It's not as nice as @Transactional
, but you get closer control of your tx status.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With