use of jakarta.transaction.SystemException in project spring-framework by spring-projects.
the class JtaTransactionManager method doCommit.
@Override
protected void doCommit(DefaultTransactionStatus status) {
JtaTransactionObject txObject = (JtaTransactionObject) status.getTransaction();
try {
int jtaStatus = txObject.getUserTransaction().getStatus();
if (jtaStatus == Status.STATUS_NO_TRANSACTION) {
// In any case, the transaction is already fully cleaned up.
throw new UnexpectedRollbackException("JTA transaction already completed - probably rolled back");
}
if (jtaStatus == Status.STATUS_ROLLEDBACK) {
// IllegalStateException expected on JBoss; call still necessary.
try {
txObject.getUserTransaction().rollback();
} catch (IllegalStateException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Rollback failure with transaction already marked as rolled back: " + ex);
}
}
throw new UnexpectedRollbackException("JTA transaction already rolled back (probably due to a timeout)");
}
txObject.getUserTransaction().commit();
} catch (RollbackException ex) {
throw new UnexpectedRollbackException("JTA transaction unexpectedly rolled back (maybe due to a timeout)", ex);
} catch (HeuristicMixedException ex) {
throw new HeuristicCompletionException(HeuristicCompletionException.STATE_MIXED, ex);
} catch (HeuristicRollbackException ex) {
throw new HeuristicCompletionException(HeuristicCompletionException.STATE_ROLLED_BACK, ex);
} catch (IllegalStateException ex) {
throw new TransactionSystemException("Unexpected internal transaction state", ex);
} catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on commit", ex);
}
}
use of jakarta.transaction.SystemException in project spring-framework by spring-projects.
the class DataSourceJtaTransactionTests method doTestJtaTransactionWithPropagationRequiresNewAndBeginException.
private void doTestJtaTransactionWithPropagationRequiresNewAndBeginException(boolean suspendException, final boolean openOuterConnection, final boolean useTransactionAwareDataSource) throws Exception {
given(userTransaction.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE, Status.STATUS_ACTIVE);
if (suspendException) {
given(transactionManager.suspend()).willThrow(new SystemException());
} else {
given(transactionManager.suspend()).willReturn(transaction);
willThrow(new SystemException()).given(userTransaction).begin();
}
given(connection.isReadOnly()).willReturn(true);
final DataSource dsToUse = useTransactionAwareDataSource ? new TransactionAwareDataSourceProxy(dataSource) : dataSource;
if (dsToUse instanceof TransactionAwareDataSourceProxy) {
((TransactionAwareDataSourceProxy) dsToUse).setReobtainTransactionalConnections(true);
}
JtaTransactionManager ptm = new JtaTransactionManager(userTransaction, transactionManager);
final TransactionTemplate tt = new TransactionTemplate(ptm);
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
boolean condition3 = !TransactionSynchronizationManager.hasResource(dsToUse);
assertThat(condition3).as("Hasn't thread connection").isTrue();
boolean condition2 = !TransactionSynchronizationManager.isSynchronizationActive();
assertThat(condition2).as("JTA synchronizations not active").isTrue();
assertThatExceptionOfType(TransactionException.class).isThrownBy(() -> tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
boolean condition = !TransactionSynchronizationManager.hasResource(dsToUse);
assertThat(condition).as("Hasn't thread connection").isTrue();
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("JTA synchronizations active").isTrue();
assertThat(status.isNewTransaction()).as("Is new transaction").isTrue();
Connection c = DataSourceUtils.getConnection(dsToUse);
try {
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
c.isReadOnly();
DataSourceUtils.releaseConnection(c, dsToUse);
c = DataSourceUtils.getConnection(dsToUse);
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
if (!openOuterConnection) {
DataSourceUtils.releaseConnection(c, dsToUse);
}
} catch (SQLException ex) {
}
try {
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
boolean condition = !TransactionSynchronizationManager.hasResource(dsToUse);
assertThat(condition).as("Hasn't thread connection").isTrue();
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("JTA synchronizations active").isTrue();
assertThat(status.isNewTransaction()).as("Is new transaction").isTrue();
Connection c = DataSourceUtils.getConnection(dsToUse);
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
DataSourceUtils.releaseConnection(c, dsToUse);
c = DataSourceUtils.getConnection(dsToUse);
assertThat(TransactionSynchronizationManager.hasResource(dsToUse)).as("Has thread connection").isTrue();
DataSourceUtils.releaseConnection(c, dsToUse);
}
});
} finally {
if (openOuterConnection) {
try {
c.isReadOnly();
DataSourceUtils.releaseConnection(c, dsToUse);
} catch (SQLException ex) {
}
}
}
}
}));
boolean condition1 = !TransactionSynchronizationManager.hasResource(dsToUse);
assertThat(condition1).as("Hasn't thread connection").isTrue();
boolean condition = !TransactionSynchronizationManager.isSynchronizationActive();
assertThat(condition).as("JTA synchronizations not active").isTrue();
verify(userTransaction).begin();
if (suspendException) {
verify(userTransaction).rollback();
}
if (suspendException) {
verify(connection, atLeastOnce()).close();
} else {
verify(connection, never()).close();
}
}
use of jakarta.transaction.SystemException in project tomcat by apache.
the class TransactionContext method setSharedConnection.
/**
* Sets the shared connection for this transaction. The shared connection is enlisted in the transaction.
*
* @param sharedConnection
* the shared connection
* @throws SQLException
* if a shared connection is already set, if XAResource for the connection could not be found in the
* transaction registry, or if there was a problem enlisting the connection in the transaction
*/
public void setSharedConnection(final Connection sharedConnection) throws SQLException {
if (this.sharedConnection != null) {
throw new IllegalStateException("A shared connection is already set");
}
// This is the first use of the connection in this transaction, so we must
// enlist it in the transaction
final Transaction transaction = getTransaction();
try {
final XAResource xaResource = transactionRegistry.getXAResource(sharedConnection);
if (!transaction.enlistResource(xaResource)) {
throw new SQLException("Unable to enlist connection in transaction: enlistResource returns 'false'.");
}
} catch (final IllegalStateException e) {
// This can happen if the transaction is already timed out
throw new SQLException("Unable to enlist connection in the transaction", e);
} catch (final RollbackException e) {
// transaction was rolled back... proceed as if there never was a transaction
} catch (final SystemException e) {
throw new SQLException("Unable to enlist connection the transaction", e);
}
this.sharedConnection = sharedConnection;
}
use of jakarta.transaction.SystemException in project spring-framework by spring-projects.
the class JtaTransactionManagerTests method jtaTransactionManagerWithSystemExceptionOnRollback.
@Test
public void jtaTransactionManagerWithSystemExceptionOnRollback() throws Exception {
UserTransaction ut = mock(UserTransaction.class);
given(ut.getStatus()).willReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE);
willThrow(new SystemException("system exception")).given(ut).rollback();
assertThatExceptionOfType(TransactionSystemException.class).isThrownBy(() -> {
JtaTransactionManager ptm = newJtaTransactionManager(ut);
TransactionTemplate tt = new TransactionTemplate(ptm);
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCompletion(int status) {
assertThat(status == TransactionSynchronization.STATUS_UNKNOWN).as("Correct completion status").isTrue();
}
});
status.setRollbackOnly();
}
});
});
verify(ut).begin();
}
use of jakarta.transaction.SystemException in project spring-framework by spring-projects.
the class JtaTransactionManagerTests method jtaTransactionManagerWithPropagationRequiresNewAndExistingWithSuspendException.
@Test
public void jtaTransactionManagerWithPropagationRequiresNewAndExistingWithSuspendException() throws Exception {
UserTransaction ut = mock(UserTransaction.class);
TransactionManager tm = mock(TransactionManager.class);
given(ut.getStatus()).willReturn(Status.STATUS_ACTIVE);
willThrow(new SystemException()).given(tm).suspend();
JtaTransactionManager ptm = newJtaTransactionManager(ut, tm);
TransactionTemplate tt = new TransactionTemplate(ptm);
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse();
assertThatExceptionOfType(TransactionSystemException.class).isThrownBy(() -> tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
}
}));
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isFalse();
}
Aggregations