| I just ran into this on 5.4.0. It is unfortunate that exceptions thrown in beforeTransactionCompletion do not result in a rollback. However, I’d like clarification from someone who is intimately familiar with the Interceptor contract. The Javadoc for beforeTransactionCompletion states
It seems given the javadoc that beforeTransactionCompletion is intended to be called after any rollback has been initiated due to error or by request. However, is it expected a RuntimeException thrown by the interceptor in beforeTransactionCompletion should rollback the exception? Naively it seems like it should. Looking at the commit history for org.hibernate.internal.SessionImpl#beforeTransactionCompletion is seems as if this exception handling logic has persisted since the initial commit available in GitHub of SessionImpl (from June 2007). The initial author must have had a reason. Looking at the call tree it seems that if we didn’t catch and swallow the exception in org.hibernate.internal.SessionImpl#beforeTransactionCompletion it would propagate to{{org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl#beforeCompletionCallback}}
private void beforeCompletionCallback() {
log.trace( "ResourceLocalTransactionCoordinatorImpl#beforeCompletionCallback" );
try {
transactionCoordinatorOwner.beforeTransactionCompletion();
synchronizationRegistry.notifySynchronizationsBeforeTransactionCompletion();
for ( TransactionObserver observer : observers() ) {
observer.beforeCompletion();
}
}
catch (RuntimeException e) {
if ( physicalTransactionDelegate != null ) {
physicalTransactionDelegate.markRollbackOnly();
}
throw e;
}
}
and then be dealt with correctly in org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.TransactionDriverControlImpl#commit
I’m going to try naively commenting out the aforementioned exception handling in org.hibernate.internal.SessionImpl#beforeTransactionCompletion on my fork and running the tests. If all existing tests pass and I write a new test asserting the rollback behavior. Will that be sufficient to get this behavior changed? |