HHH-9976 - JdbcResourceLocalTransactionCoordinatorImpl does not rollback on failure during #commit
This commit is contained in:
parent
3d1a39f80d
commit
16c0a1f144
|
@ -21,6 +21,7 @@ import static org.hibernate.resource.transaction.TransactionCoordinator.Transact
|
|||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TransactionImpl implements Transaction {
|
||||
private static final Logger LOG = CoreLogging.logger( TransactionImpl.class );
|
||||
|
@ -71,6 +72,13 @@ public class TransactionImpl implements Transaction {
|
|||
@Override
|
||||
public void rollback() {
|
||||
TransactionStatus status = transactionDriverControl.getStatus();
|
||||
if ( status == TransactionStatus.ROLLED_BACK || status == TransactionStatus.NOT_ACTIVE ) {
|
||||
// Allow rollback() calls on completed transactions, just no-op.
|
||||
LOG.debug( "rollback() called on an inactive transaction" );
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !status.canRollback() ) {
|
||||
throw new TransactionException( "Cannot rollback transaction in current status [" + status.name() + "]" );
|
||||
}
|
||||
|
|
|
@ -222,19 +222,35 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
|
|||
|
||||
@Override
|
||||
public void commit() {
|
||||
if ( rollbackOnly ) {
|
||||
throw new TransactionException( "Transaction was marked for rollback only; cannot commit" );
|
||||
}
|
||||
try {
|
||||
if ( rollbackOnly ) {
|
||||
throw new TransactionException( "Transaction was marked for rollback only; cannot commit" );
|
||||
}
|
||||
|
||||
JdbcResourceLocalTransactionCoordinatorImpl.this.beforeCompletionCallback();
|
||||
jdbcResourceTransaction.commit();
|
||||
JdbcResourceLocalTransactionCoordinatorImpl.this.afterCompletionCallback( true );
|
||||
JdbcResourceLocalTransactionCoordinatorImpl.this.beforeCompletionCallback();
|
||||
jdbcResourceTransaction.commit();
|
||||
JdbcResourceLocalTransactionCoordinatorImpl.this.afterCompletionCallback( true );
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
try {
|
||||
rollback();
|
||||
}
|
||||
catch (RuntimeException e2) {
|
||||
log.debug( "Encountered failure rolling back failed commit", e2 );;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() {
|
||||
jdbcResourceTransaction.rollback();
|
||||
JdbcResourceLocalTransactionCoordinatorImpl.this.afterCompletionCallback( false );
|
||||
if ( rollbackOnly || getStatus() == TransactionStatus.ACTIVE ) {
|
||||
rollbackOnly = false;
|
||||
jdbcResourceTransaction.rollback();
|
||||
JdbcResourceLocalTransactionCoordinatorImpl.this.afterCompletionCallback( false );
|
||||
}
|
||||
|
||||
// no-op otherwise.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -106,7 +106,7 @@ public class SynchronizationRegistryStandardImplTests {
|
|||
// exception in beforeCompletion
|
||||
registry.clearSynchronizations();
|
||||
registry = new SynchronizationRegistryStandardImpl();
|
||||
synchronization = new SynchronizationErrorImpl( false, true );
|
||||
synchronization = SynchronizationErrorImpl.forAfter();
|
||||
registry.registerSynchronization( synchronization );
|
||||
try {
|
||||
registry.notifySynchronizationsAfterTransactionCompletion( Status.STATUS_COMMITTED );
|
||||
|
|
|
@ -88,14 +88,13 @@ public class BasicJdbcTransactionTests {
|
|||
catch (TransactionException expected) {
|
||||
}
|
||||
finally {
|
||||
assertEquals( TransactionStatus.MARKED_ROLLBACK, transactionCoordinator.getTransactionDriverControl().getStatus() );
|
||||
transactionCoordinator.getTransactionDriverControl().rollback();
|
||||
assertEquals( TransactionStatus.NOT_ACTIVE, transactionCoordinator.getTransactionDriverControl().getStatus() );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("EmptyCatchBlock")
|
||||
public void testSynchronizationFailureMarksTransactionForRollbackOnly() {
|
||||
public void testSynchronizationFailure() {
|
||||
final TransactionCoordinatorOwnerTestingImpl owner = new TransactionCoordinatorOwnerTestingImpl();
|
||||
final JdbcResourceLocalTransactionCoordinatorBuilderImpl transactionCoordinatorBuilder =
|
||||
new JdbcResourceLocalTransactionCoordinatorBuilderImpl();
|
||||
|
@ -122,8 +121,10 @@ public class BasicJdbcTransactionTests {
|
|||
catch (Exception expected) {
|
||||
}
|
||||
finally {
|
||||
assertEquals( TransactionStatus.MARKED_ROLLBACK, transactionCoordinator.getTransactionDriverControl().getStatus() );
|
||||
transactionCoordinator.getTransactionDriverControl().rollback();
|
||||
assertEquals(
|
||||
TransactionStatus.NOT_ACTIVE,
|
||||
transactionCoordinator.getTransactionDriverControl().getStatus()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -401,14 +401,13 @@ public abstract class AbstractBasicJtaTestScenarios {
|
|||
catch (TransactionException expected) {
|
||||
}
|
||||
finally {
|
||||
assertEquals( TransactionStatus.MARKED_ROLLBACK, transactionCoordinator.getTransactionDriverControl().getStatus() );
|
||||
transactionCoordinator.getTransactionDriverControl().rollback();
|
||||
assertEquals( TransactionStatus.NOT_ACTIVE, transactionCoordinator.getTransactionDriverControl().getStatus() );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("EmptyCatchBlock")
|
||||
public void testSynchronizationFailureMarksTransactionForRollbackOnly() throws Exception {
|
||||
public void testSynchronizationFailure() throws Exception {
|
||||
JtaTransactionCoordinatorImpl transactionCoordinator = new JtaTransactionCoordinatorImpl(
|
||||
transactionCoordinatorBuilder,
|
||||
owner,
|
||||
|
@ -434,8 +433,7 @@ public abstract class AbstractBasicJtaTestScenarios {
|
|||
catch (Exception expected) {
|
||||
}
|
||||
finally {
|
||||
assertEquals( TransactionStatus.MARKED_ROLLBACK, transactionCoordinator.getTransactionDriverControl().getStatus() );
|
||||
transactionCoordinator.getTransactionDriverControl().rollback();
|
||||
assertEquals( TransactionStatus.NOT_ACTIVE, transactionCoordinator.getTransactionDriverControl().getStatus() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue