Search in sources :

Example 36 with SubordinateTransaction

use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction 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 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<SubordinateTransaction> holder = new AtomicReference<>();
    AtomicReference<SubordinateTransaction> existing;
    if ((existing = _transactions.putIfAbsent(importedXid, holder)) != null) {
        holder = existing;
    }
    SubordinateTransaction 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);
}
Also used : SubordinateXidImple(com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateXidImple) TransactionImportResult(org.jboss.tm.TransactionImportResult) TransactionImple(com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple) AtomicReference(java.util.concurrent.atomic.AtomicReference) SubordinateTransaction(com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction)

Example 37 with SubordinateTransaction

use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction in project narayana by jbosstm.

the class TransactionImporterUnitTest method testDifferentInstanceFromRecovery.

@Test
public void testDifferentInstanceFromRecovery() throws XAException, RollbackException, SystemException, HeuristicRollbackException, HeuristicMixedException, HeuristicCommitException, NoSuchFieldException, IllegalAccessException {
    Uid uid = new Uid();
    XidImple xid = new XidImple(uid);
    SubordinateTransaction subordinateTransaction = SubordinationManager.getTransactionImporter().importTransaction(xid);
    // This is required because it JTS records are stored with a dynamic _savingUid
    // Normally they are recovered using XATerminator but for this test I would like to stick to testing
    // transaction importer
    Field field = TransactionImple.class.getDeclaredField("_theTransaction");
    field.setAccessible(true);
    Object o = field.get(subordinateTransaction);
    field = AtomicTransaction.class.getDeclaredField("_theAction");
    field.setAccessible(true);
    o = field.get(o);
    field = ControlWrapper.class.getDeclaredField("_controlImpl");
    field.setAccessible(true);
    o = field.get(o);
    field = ControlImple.class.getDeclaredField("_transactionHandle");
    field.setAccessible(true);
    o = field.get(o);
    field = ServerTransaction.class.getDeclaredField("_savingUid");
    field.setAccessible(true);
    Uid subordinateTransactionUid = (Uid) field.get(o);
    Xid subordinateTransactionXid = subordinateTransaction.baseXid();
    SubordinateTransaction importedTransaction = SubordinationManager.getTransactionImporter().getImportedTransaction(subordinateTransactionXid);
    assertTrue(subordinateTransaction == importedTransaction);
    subordinateTransaction.enlistResource(new XAResource() {

        @Override
        public void commit(Xid xid, boolean b) throws XAException {
        }

        @Override
        public void end(Xid xid, int i) throws XAException {
        }

        @Override
        public void forget(Xid xid) throws XAException {
        }

        @Override
        public int getTransactionTimeout() throws XAException {
            return 0;
        }

        @Override
        public boolean isSameRM(XAResource xaResource) throws XAException {
            return false;
        }

        @Override
        public int prepare(Xid xid) throws XAException {
            return 0;
        }

        @Override
        public Xid[] recover(int i) throws XAException {
            return new Xid[0];
        }

        @Override
        public void rollback(Xid xid) throws XAException {
        }

        @Override
        public boolean setTransactionTimeout(int i) throws XAException {
            return false;
        }

        @Override
        public void start(Xid xid, int i) throws XAException {
        }
    });
    subordinateTransaction.doPrepare();
    Implementationsx.initialise();
    SubordinateTransaction subordinateTransaction1 = SubordinationManager.getTransactionImporter().recoverTransaction(subordinateTransactionUid);
    assertTrue(subordinateTransaction != subordinateTransaction1);
    SubordinateTransaction importedTransaction1 = SubordinationManager.getTransactionImporter().getImportedTransaction(subordinateTransactionXid);
    assertTrue(importedTransaction != importedTransaction1);
    SubordinateTransaction importedTransaction2 = SubordinationManager.getTransactionImporter().getImportedTransaction(subordinateTransactionXid);
    assertTrue(importedTransaction1 == importedTransaction2);
    importedTransaction2.doCommit();
}
Also used : XidImple(com.arjuna.ats.jta.xa.XidImple) XAException(javax.transaction.xa.XAException) Uid(com.arjuna.ats.arjuna.common.Uid) Field(java.lang.reflect.Field) Xid(javax.transaction.xa.Xid) XAResource(javax.transaction.xa.XAResource) AtomicTransaction(com.arjuna.ats.jts.extensions.AtomicTransaction) ControlWrapper(com.arjuna.ats.internal.jts.ControlWrapper) SubordinateTransaction(com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction) ServerTransaction(com.arjuna.ats.internal.jts.orbspecific.interposition.coordinator.ServerTransaction) ControlImple(com.arjuna.ats.internal.jts.orbspecific.ControlImple) Test(org.junit.Test)

Example 38 with SubordinateTransaction

use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction in project narayana by jbosstm.

the class XATerminatorImpleUnitTest method testMoveToAssumedComplete.

@Test
public void testMoveToAssumedComplete() throws Exception {
    Implementations.initialise();
    Implementationsx.initialise();
    Uid uid = new Uid();
    Xid xid = XidUtils.getXid(uid, false);
    XATerminatorImple xaTerminator = new XATerminatorImple();
    TransactionImporter importer = SubordinationManager.getTransactionImporter();
    SubordinateTransaction subordinateTransaction = importer.importTransaction(xid);
    Uid subordinateTransactionUid = getImportedSubordinateTransactionUid(subordinateTransaction);
    com.hp.mwtests.ts.jta.subordinate.TestXAResource xares = new com.hp.mwtests.ts.jta.subordinate.TestXAResource();
    xares.setCommitException(new XAException(XAException.XAER_RMFAIL));
    subordinateTransaction.enlistResource(xares);
    subordinateTransaction.doPrepare();
    boolean commitFailed = subordinateTransaction.doCommit();
    Assert.assertFalse("Commit should fail as XAResource defined XAException on commit being thrown", commitFailed);
    int assumedCompletedRetryOriginalValue = jtsPropertyManager.getJTSEnvironmentBean().getCommitedTransactionRetryLimit();
    jtsPropertyManager.getJTSEnvironmentBean().setCommitedTransactionRetryLimit(1);
    try {
        SubordinateTransaction recoveredTxn = importer.recoverTransaction(subordinateTransactionUid);
        Xid xidRecovered = recoveredTxn.baseXid();
        Assert.assertEquals("recovered subordinate xid should be equal to imported one", xid, xidRecovered);
        Runnable runCommitExpectingException = () -> {
            try {
                // importing transaction
                xaTerminator.recover(XAResource.TMSTARTRSCAN);
                xaTerminator.recover(XAResource.TMENDRSCAN);
                // try to commit the imported transaction
                xaTerminator.commit(xid, false);
                Assert.fail("XAException is expected to be thrown as txn was not yet moved to assumed complete state");
            } catch (XAException expected) {
                Assert.assertTrue("Commit expect to throw exception indicating that othe commit call is expected, but error code is " + expected.errorCode, XAException.XA_RETRY == expected.errorCode || XAException.XAER_RMFAIL == expected.errorCode);
            }
        };
        // replay first
        runCommitExpectingException.run();
        // assume completed check first time
        runCommitExpectingException.run();
        // importing transaction
        xaTerminator.recover(XAResource.TMSTARTRSCAN);
        xaTerminator.recover(XAResource.TMENDRSCAN);
        // moving to assumed completed state
        xaTerminator.commit(xid, false);
    } finally {
        jtsPropertyManager.getJTSEnvironmentBean().setCommitedTransactionRetryLimit(assumedCompletedRetryOriginalValue);
    }
    try {
        importer.recoverTransaction(subordinateTransactionUid);
        Assert.fail("Transaction '" + subordinateTransaction + "' should fail to recover as it should be moved " + "to category AssumedCompleteServerTrasactions");
    } catch (IllegalArgumentException expected) {
    }
    ObjectStoreIterator objectStoreIterator = new ObjectStoreIterator(StoreManager.getRecoveryStore(), AssumedCompleteServerTransaction.typeName());
    List<Uid> assumedCompletedUids = new ArrayList<Uid>();
    Uid iteratedUid = objectStoreIterator.iterate();
    while (Uid.nullUid().notEquals(iteratedUid)) {
        assumedCompletedUids.add(iteratedUid);
        iteratedUid = objectStoreIterator.iterate();
    }
    Assert.assertTrue("the subordinate transaction has to be moved under assumed completed in object store", assumedCompletedUids.contains(subordinateTransactionUid));
}
Also used : TestXAResource(com.hp.mwtests.ts.jta.jts.TestXAResource) XAException(javax.transaction.xa.XAException) ObjectStoreIterator(com.arjuna.ats.arjuna.objectstore.ObjectStoreIterator) ArrayList(java.util.ArrayList) Uid(com.arjuna.ats.arjuna.common.Uid) Xid(javax.transaction.xa.Xid) TransactionImporter(com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TransactionImporter) XATerminatorImple(com.arjuna.ats.internal.jta.transaction.jts.jca.XATerminatorImple) SubordinateTransaction(com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction) Test(org.junit.Test)

Example 39 with SubordinateTransaction

use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction in project narayana by jbosstm.

the class XATerminatorImpleUnitTest method testImportMultipleTx.

@Test
public void testImportMultipleTx() throws XAException, RollbackException, SystemException {
    Implementations.initialise();
    Implementationsx.initialise();
    XidImple xid = new XidImple(new Uid());
    TransactionImporter imp = SubordinationManager.getTransactionImporter();
    SubordinateTransaction subordinateTransaction = imp.importTransaction(xid);
    XATerminatorImple xa = new XATerminatorImple();
    XAResourceImple xar1 = new XAResourceImple(XAResource.XA_OK);
    XAResourceImple xar2 = new XAResourceImple(XAException.XAER_RMFAIL);
    subordinateTransaction.enlistResource(xar1);
    subordinateTransaction.enlistResource(xar2);
    xa.prepare(xid);
    try {
        xa.commit(xid, false);
        fail("Did not expect to pass");
    } catch (XAException xae) {
        assertTrue(xae.errorCode == XAException.XAER_RMFAIL);
    }
    Xid[] xids = xa.recover(XAResource.TMSTARTRSCAN);
    assertTrue(Arrays.binarySearch(xids, xid, new Comparator<Xid>() {

        @Override
        public int compare(Xid o1, Xid o2) {
            if (((XidImple) o1).equals(o2)) {
                return 0;
            } else {
                return -1;
            }
        }
    }) != -1);
    // Will throw a heuristic. The doRollback should be allowed but when we realise that the XAR1 is commited it shouldn't be allowed. Maybe we should also not shutdown the first XAR or maybe we need to rely on bottom up.
    xa.rollback(xid);
    assertTrue(xar2.rollbackCalled());
    xa.recover(XAResource.TMENDRSCAN);
}
Also used : XidImple(com.arjuna.ats.jta.xa.XidImple) Uid(com.arjuna.ats.arjuna.common.Uid) Xid(javax.transaction.xa.Xid) XAException(javax.transaction.xa.XAException) TransactionImporter(com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TransactionImporter) XATerminatorImple(com.arjuna.ats.internal.jta.transaction.jts.jca.XATerminatorImple) SubordinateTransaction(com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction) Test(org.junit.Test)

Example 40 with SubordinateTransaction

use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction in project narayana by jbosstm.

the class SubordinateTestCase method testPrepareRollback.

@Test
public void testPrepareRollback() throws Exception {
    final SubordinateTransaction tm = createTransaction();
    assertEquals(TwoPhaseOutcome.PREPARE_READONLY, tm.doPrepare());
    try {
        tm.doRollback();
        fail("TransactionImple stub can't be sure why the transaction was committed it shouldn't massage");
    } catch (HeuristicMixedException e) {
    // TransactionImple stub can't be sure why the transaction was committed it shouldn't massage
    // - this DOES NOT match doPhase2Abort in ServerTransaction which allows a massage
    }
}
Also used : HeuristicMixedException(javax.transaction.HeuristicMixedException) SubordinateTransaction(com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction) Test(org.junit.Test)

Aggregations

SubordinateTransaction (com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction)42 Test (org.junit.Test)35 XAException (javax.transaction.xa.XAException)18 Uid (com.arjuna.ats.arjuna.common.Uid)16 Xid (javax.transaction.xa.Xid)13 XidImple (com.arjuna.ats.jta.xa.XidImple)12 TransactionImporter (com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TransactionImporter)7 XATerminatorImple (com.arjuna.ats.internal.jta.transaction.jts.jca.XATerminatorImple)6 RollbackException (javax.transaction.RollbackException)6 SystemException (javax.transaction.SystemException)6 XAResource (javax.transaction.xa.XAResource)6 XATerminatorImple (com.arjuna.ats.internal.jta.transaction.arjunacore.jca.XATerminatorImple)4 ArrayList (java.util.ArrayList)4 XARecoveryModule (com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule)3 SubordinateXidImple (com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateXidImple)3 UnexpectedConditionException (com.arjuna.ats.jta.exceptions.UnexpectedConditionException)3 XAResourceRecoveryHelper (com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper)3 TestXAResource (com.hp.mwtests.ts.jta.jts.TestXAResource)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 HeuristicMixedException (javax.transaction.HeuristicMixedException)3