use of cn.taketoday.transaction.UnexpectedRollbackException in project today-infrastructure by TAKETODAY.
the class JdbcTransactionManagerTests method doTestParticipatingTransactionWithRollbackOnly.
private void doTestParticipatingTransactionWithRollbackOnly(boolean failEarly) throws Exception {
given(con.isReadOnly()).willReturn(false);
if (failEarly) {
tm.setFailEarlyOnGlobalRollbackOnly(true);
}
boolean condition2 = !TransactionSynchronizationManager.hasResource(ds);
assertThat(condition2).as("Hasn't thread connection").isTrue();
boolean condition1 = !TransactionSynchronizationManager.isSynchronizationActive();
assertThat(condition1).as("Synchronization not active").isTrue();
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
TestTransactionSynchronization synch = new TestTransactionSynchronization(ds, TransactionSynchronization.STATUS_ROLLED_BACK);
TransactionSynchronizationManager.registerSynchronization(synch);
boolean outerTransactionBoundaryReached = false;
try {
assertThat(ts.isNewTransaction()).as("Is new transaction").isTrue();
final TransactionTemplate tt = new TransactionTemplate(tm);
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
boolean condition1 = !status.isNewTransaction();
assertThat(condition1).as("Is existing transaction").isTrue();
assertThat(status.isRollbackOnly()).as("Is not rollback-only").isFalse();
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
assertThat(TransactionSynchronizationManager.hasResource(ds)).as("Has thread connection").isTrue();
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("Synchronization active").isTrue();
boolean condition = !status.isNewTransaction();
assertThat(condition).as("Is existing transaction").isTrue();
status.setRollbackOnly();
}
});
boolean condition = !status.isNewTransaction();
assertThat(condition).as("Is existing transaction").isTrue();
assertThat(status.isRollbackOnly()).as("Is rollback-only").isTrue();
}
});
outerTransactionBoundaryReached = true;
tm.commit(ts);
fail("Should have thrown UnexpectedRollbackException");
} catch (UnexpectedRollbackException ex) {
// expected
if (!outerTransactionBoundaryReached) {
tm.rollback(ts);
}
if (failEarly) {
assertThat(outerTransactionBoundaryReached).isFalse();
} else {
assertThat(outerTransactionBoundaryReached).isTrue();
}
}
boolean condition = !TransactionSynchronizationManager.hasResource(ds);
assertThat(condition).as("Hasn't thread connection").isTrue();
assertThat(synch.beforeCommitCalled).isFalse();
assertThat(synch.beforeCompletionCalled).isTrue();
assertThat(synch.afterCommitCalled).isFalse();
assertThat(synch.afterCompletionCalled).isTrue();
verify(con).rollback();
verify(con).close();
}
use of cn.taketoday.transaction.UnexpectedRollbackException in project today-infrastructure by TAKETODAY.
the class AbstractReactiveTransactionAspectTests method cannotCommitTransaction.
/**
* Simulate failure of the underlying transaction infrastructure to commit.
* Check that the target method was invoked, but that the transaction
* infrastructure exception was thrown to the client
*/
@Test
public void cannotCommitTransaction() throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute();
Method m = setNameMethod;
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(m, txatt);
// Method m2 = getNameMethod;
// No attributes for m2
ReactiveTransactionManager rtm = mock(ReactiveTransactionManager.class);
ReactiveTransaction status = mock(ReactiveTransaction.class);
given(rtm.getReactiveTransaction(txatt)).willReturn(Mono.just(status));
UnexpectedRollbackException ex = new UnexpectedRollbackException("foobar", null);
given(rtm.commit(status)).willReturn(Mono.error(ex));
given(rtm.rollback(status)).willReturn(Mono.empty());
DefaultTestBean tb = new DefaultTestBean();
TestBean itb = (TestBean) advised(tb, rtm, tas);
String name = "new name";
Mono.from(itb.setName(name)).as(StepVerifier::create).consumeErrorWith(throwable -> {
assertThat(throwable.getClass()).isEqualTo(RuntimeException.class);
assertThat(throwable.getCause()).isEqualTo(ex);
}).verify();
// Should have invoked target and changed name
itb.getName().as(StepVerifier::create).expectNext(name).verifyComplete();
}
use of cn.taketoday.transaction.UnexpectedRollbackException in project today-framework by TAKETODAY.
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.toString());
}
}
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 cn.taketoday.transaction.UnexpectedRollbackException in project today-framework by TAKETODAY.
the class JdbcTransactionManagerTests method doTestParticipatingTransactionWithRollbackOnly.
private void doTestParticipatingTransactionWithRollbackOnly(boolean failEarly) throws Exception {
given(con.isReadOnly()).willReturn(false);
if (failEarly) {
tm.setFailEarlyOnGlobalRollbackOnly(true);
}
boolean condition2 = !TransactionSynchronizationManager.hasResource(ds);
assertThat(condition2).as("Hasn't thread connection").isTrue();
boolean condition1 = !TransactionSynchronizationManager.isSynchronizationActive();
assertThat(condition1).as("Synchronization not active").isTrue();
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
TestTransactionSynchronization synch = new TestTransactionSynchronization(ds, TransactionSynchronization.STATUS_ROLLED_BACK);
TransactionSynchronizationManager.registerSynchronization(synch);
boolean outerTransactionBoundaryReached = false;
try {
assertThat(ts.isNewTransaction()).as("Is new transaction").isTrue();
final TransactionTemplate tt = new TransactionTemplate(tm);
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
boolean condition1 = !status.isNewTransaction();
assertThat(condition1).as("Is existing transaction").isTrue();
assertThat(status.isRollbackOnly()).as("Is not rollback-only").isFalse();
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException {
assertThat(TransactionSynchronizationManager.hasResource(ds)).as("Has thread connection").isTrue();
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).as("Synchronization active").isTrue();
boolean condition = !status.isNewTransaction();
assertThat(condition).as("Is existing transaction").isTrue();
status.setRollbackOnly();
}
});
boolean condition = !status.isNewTransaction();
assertThat(condition).as("Is existing transaction").isTrue();
assertThat(status.isRollbackOnly()).as("Is rollback-only").isTrue();
}
});
outerTransactionBoundaryReached = true;
tm.commit(ts);
fail("Should have thrown UnexpectedRollbackException");
} catch (UnexpectedRollbackException ex) {
// expected
if (!outerTransactionBoundaryReached) {
tm.rollback(ts);
}
if (failEarly) {
assertThat(outerTransactionBoundaryReached).isFalse();
} else {
assertThat(outerTransactionBoundaryReached).isTrue();
}
}
boolean condition = !TransactionSynchronizationManager.hasResource(ds);
assertThat(condition).as("Hasn't thread connection").isTrue();
assertThat(synch.beforeCommitCalled).isFalse();
assertThat(synch.beforeCompletionCalled).isTrue();
assertThat(synch.afterCommitCalled).isFalse();
assertThat(synch.afterCompletionCalled).isTrue();
verify(con).rollback();
verify(con).close();
}
use of cn.taketoday.transaction.UnexpectedRollbackException in project today-framework by TAKETODAY.
the class AbstractReactiveTransactionAspectTests method cannotCommitTransaction.
/**
* Simulate failure of the underlying transaction infrastructure to commit.
* Check that the target method was invoked, but that the transaction
* infrastructure exception was thrown to the client
*/
@Test
public void cannotCommitTransaction() throws Exception {
TransactionAttribute txatt = new DefaultTransactionAttribute();
Method m = setNameMethod;
MapTransactionAttributeSource tas = new MapTransactionAttributeSource();
tas.register(m, txatt);
// Method m2 = getNameMethod;
// No attributes for m2
ReactiveTransactionManager rtm = mock(ReactiveTransactionManager.class);
ReactiveTransaction status = mock(ReactiveTransaction.class);
given(rtm.getReactiveTransaction(txatt)).willReturn(Mono.just(status));
UnexpectedRollbackException ex = new UnexpectedRollbackException("foobar", null);
given(rtm.commit(status)).willReturn(Mono.error(ex));
given(rtm.rollback(status)).willReturn(Mono.empty());
DefaultTestBean tb = new DefaultTestBean();
TestBean itb = (TestBean) advised(tb, rtm, tas);
String name = "new name";
Mono.from(itb.setName(name)).as(StepVerifier::create).consumeErrorWith(throwable -> {
assertThat(throwable.getClass()).isEqualTo(RuntimeException.class);
assertThat(throwable.getCause()).isEqualTo(ex);
}).verify();
// Should have invoked target and changed name
itb.getName().as(StepVerifier::create).expectNext(name).verifyComplete();
}
Aggregations