In Spring Boot 3.x I have transactional-event-listeners. One is bound to phase “BEFORE_COMMIT” and responsible for doing some “last millisecond checks” before the transaction finally commits towards the database:
@TransactionalEventListener(
phase = TransactionPhase.BEFORE_COMMIT,
fallbackExecution = true)
public void processPreCommit(MyPreEvent event) {...}
If this check fails, then I need to rollback the transaction. Unfortunately, non of my actions has any affect on the ongoing transaction. I know this, because I also have an “AFTER_COMMIT” transaction listener which should only run in case of a successfully completed transaction but is also executed in case I rollback within the BEFORE_COMMIT transaction listener:
@TransactionalEventListener(
phase = TransactionPhase.AFTER_COMMIT,
fallbackExecution = true)
public void processPostCommit(MyPostEvent event) {...}
Rolling back is not that easy within a BEFORE_COMMIT transaction listener. Typically this is done by
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
In the context of the listener the TransactionAspectSupport does not work any more, so I passed the method setRoolbackOnly
into the event and run it within the event listener. This runs without an error but does not rollback the transaction:
// on sending the event within the transaction:
final var tx = TransactionAspectSupport.currentTransactionStatus();
publisher.publishEvent(new MyPreEvent(tx::setRollbackOnly));
...
// in the BEFORE_COMMIT transaction listener:
if (TransactionSynchronizationManager.isActualTransactionActive()) {
event.setRollbackOnly.run();
}
Has anyone an idea how to rollback in that special situation?
Thx, Stephan