use of com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple in project narayana by jbosstm.
the class SubordinateTestCase method testOnePhaseCommitSyncWithRollbackOnlyViaXATerminatorWithSeparateSync.
@Test
public void testOnePhaseCommitSyncWithRollbackOnlyViaXATerminatorWithSeparateSync() throws Exception {
final Xid xid = new XidImple(new Uid());
final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
final TestSynchronization sync = new TestSynchronization();
t.registerSynchronization(sync);
t.setRollbackOnly();
final XATerminator xaTerminator = SubordinationManager.getXATerminator();
final XATerminatorExtensions xaTerminatorExtensions = (XATerminatorExtensions) xaTerminator;
xaTerminatorExtensions.beforeCompletion(xid);
try {
xaTerminator.commit(xid, true);
((TransactionImple) t).doOnePhaseCommit();
fail("did not get expected rollback exception");
} catch (XAException e) {
assertEquals("javax.transaction.RollbackException", e.getCause().getClass().getName());
assertEquals(XAException.XA_RBROLLBACK, e.errorCode);
// expected - we tried to commit a rollbackonly tx.
}
assertTrue(sync.isBeforeCompletionDone());
assertTrue(sync.isAfterCompletionDone());
assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
}
use of com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple in project narayana by jbosstm.
the class SubordinateTestCase method testOnePhaseCommitSyncWithRollbackOnlyViaXATerminator.
@Test
public void testOnePhaseCommitSyncWithRollbackOnlyViaXATerminator() throws Exception {
final Xid xid = new XidImple(new Uid());
final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
final TestSynchronization sync = new TestSynchronization();
t.registerSynchronization(sync);
t.setRollbackOnly();
final XATerminator xaTerminator = SubordinationManager.getXATerminator();
try {
xaTerminator.commit(xid, true);
((TransactionImple) t).doOnePhaseCommit();
fail("did not get expected rollback exception");
} catch (XAException e) {
assertEquals("javax.transaction.RollbackException", e.getCause().getClass().getName());
assertEquals(XAException.XA_RBROLLBACK, e.errorCode);
// expected - we tried to commit a rollbackonly tx.
}
assertFalse(sync.isBeforeCompletionDone());
assertTrue(sync.isAfterCompletionDone());
assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
}
use of com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple in project narayana by jbosstm.
the class SubordinateTxUnitTest method testTransactionImple.
@Test
public void testTransactionImple() throws Exception {
TransactionImple tx = new TransactionImple(new Uid());
TransactionImple dummy = new TransactionImple(new Uid());
tx.recordTransaction();
assertFalse(tx.equals(dummy));
assertTrue(tx.toString() != null);
tx.recover();
}
use of com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple in project narayana by jbosstm.
the class TransactionImporterImple method getImportedTransaction.
/**
* Get the subordinate (imported) transaction associated with the global
* transaction.
*
* @param xid
* the global transaction.
*
* @return the subordinate transaction or <code>null</code> if there is
* none.
*
* @throws javax.transaction.xa.XAException
* thrown if there are any errors.
*/
public SubordinateTransaction getImportedTransaction(Xid xid) throws XAException {
if (xid == null)
throw new IllegalArgumentException();
AtomicReference<TransactionImple> holder = _transactions.get(new SubordinateXidImple(xid));
TransactionImple tx = holder == null ? null : holder.get();
if (tx == null) {
/*
* Remark: if holder != null and holder.get() == null then the setter is about to
* import the transaction but has not yet updated the holder. We implement the getter
* (the thing that is trying to terminate the imported transaction) as though the imported
* transaction only becomes observable when it has been fully imported.
*/
return null;
}
// https://issues.jboss.org/browse/JBTM-927
try {
if (tx.getStatus() == javax.transaction.Status.STATUS_ROLLEDBACK) {
throw new XAException(XAException.XA_RBROLLBACK);
}
} catch (SystemException e) {
e.printStackTrace();
throw new XAException(XAException.XA_RBROLLBACK);
}
if (!tx.activated()) {
tx.recover();
return tx;
} else
return tx;
}
use of com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple in project narayana by jbosstm.
the class TransactionImporterImple method addImportedTransaction.
/**
* This can be used for newly imported transactions or recovered ones.
*
* @param recoveredTransaction If this is recovery
* @param mapKey
* @param xid if this is import
* @param timeout
* @return
*/
private TransactionImportResult addImportedTransaction(TransactionImple recoveredTransaction, Xid mapKey, Xid xid, int timeout) {
boolean isNew = false;
SubordinateXidImple importedXid = new SubordinateXidImple(mapKey);
// We need to store the imported transaction in a volatile field holder so that it can be shared between threads
AtomicReference<TransactionImple> holder = new AtomicReference<>();
AtomicReference<TransactionImple> existing;
if ((existing = _transactions.putIfAbsent(importedXid, holder)) != null) {
holder = existing;
}
TransactionImple txn = holder.get();
// Should only be called by the recovery system - this will replace the Transaction with one from disk
if (recoveredTransaction != null) {
synchronized (holder) {
// now it's safe to add the imported transaction to the holder
recoveredTransaction.recordTransaction();
txn = recoveredTransaction;
holder.set(txn);
holder.notifyAll();
}
}
if (txn == null) {
// a volatile so can be concurrently accessed by multiple threads
synchronized (holder) {
txn = holder.get();
if (txn == null) {
txn = new TransactionImple(timeout, xid);
holder.set(txn);
holder.notifyAll();
isNew = true;
}
}
}
return new TransactionImportResult(txn, isNew);
}
Aggregations