use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction in project narayana by jbosstm.
the class XATerminatorImpleUnitTest method testDoRecover.
@Test
public void testDoRecover() throws Exception {
Implementations.initialise();
Implementationsx.initialise();
Xid xid1 = XidUtils.getXid(new Uid(), false);
Xid xid2 = XidUtils.getXid(new Uid(), false);
TransactionImporter imp = SubordinationManager.getTransactionImporter();
SubordinateTransaction subTxn1 = imp.importTransaction(xid1);
SubordinateTransaction subTxn2 = imp.importTransaction(xid2);
XATerminatorImple xaTerminator = new XATerminatorImple();
subTxn1.enlistResource(new XAResourceImple(XAResource.XA_OK));
subTxn2.enlistResource(new XAResourceImple(XAResource.XA_OK));
try {
subTxn1.doPrepare();
subTxn2.doPrepare();
Xid[] xidsAll = xaTerminator.doRecover(null, null);
Assert.assertNotNull("expecting some unfinished transactions to be returned but they are null", xidsAll);
Assert.assertTrue("expecting some unfinished transactions to be returned but there is none", xidsAll.length > 1);
} finally {
subTxn1.doCommit();
subTxn2.doCommit();
}
}
use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction in project narayana by jbosstm.
the class XATerminatorImpleUnitTest method testXARMERR.
@Test
public void testXARMERR() throws Exception {
Uid uid = new Uid();
XidImple xid = new XidImple(uid);
TransactionImporter imp = SubordinationManager.getTransactionImporter();
SubordinateTransaction subordinateTransaction = imp.importTransaction(xid);
Uid savingUid = getImportedSubordinateTransactionUid(subordinateTransaction);
subordinateTransaction.enlistResource(new TestXAResource() {
@Override
public void commit(Xid xid, boolean b) throws XAException {
this.xid = null;
}
@Override
public int prepare(Xid xid) throws XAException {
return 0;
}
@Override
public void rollback(Xid xid) throws XAException {
fail("Resource was rolled back");
}
});
subordinateTransaction.enlistResource(new TestXAResource() {
@Override
public void commit(Xid xid, boolean b) throws XAException {
throw new XAException(XAException.XA_HEURHAZ);
}
@Override
public int prepare(Xid xid) throws XAException {
failedResourceXid = xid;
return 0;
}
@Override
public void rollback(Xid xid) throws XAException {
fail("Resource was rolled back");
}
});
XATerminatorImple xa = new XATerminatorImple();
xa.prepare(xid);
try {
xa.commit(xid, false);
fail("Expecting heuristic mixed exception being thrown on commit");
} catch (final XAException ex) {
assertEquals(XAException.XA_HEURMIX, ex.errorCode);
}
try {
xa.commit(xid, false);
} catch (XAException e) {
assertEquals(XAException.XA_RETRY, e.errorCode);
}
ObjStoreBrowser osb = new ObjStoreBrowser();
osb.viewSubordinateAtomicActions(true);
osb.setExposeAllRecordsAsMBeans(true);
osb.start();
osb.probe();
Set<ObjectName> participants = JMXServer.getAgent().queryNames("jboss.jta:type=ObjectStore,itype=" + com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.coordinator.ServerTransaction.getType().substring(1) + ",uid=" + savingUid.stringForm().replaceAll(":", "_") + ",puid=*", null);
assertEquals(1, participants.size());
JMXServer.getAgent().getServer().invoke(participants.iterator().next(), "clearHeuristic", null, null);
xa.recover(XAResource.TMSTARTRSCAN);
xa.recover(XAResource.TMENDRSCAN);
Set<ObjectName> xaResourceRecords = JMXServer.getAgent().queryNames("jboss.jta:type=ObjectStore,itype=" + XAResourceRecord.typeName().substring(1) + ",uid=*", null);
for (ObjectName xaResourceRecord : xaResourceRecords) {
Object getGlobalTransactionId = JMXServer.getAgent().getServer().getAttribute(xaResourceRecord, "GlobalTransactionId");
Object getBranchQualifier = JMXServer.getAgent().getServer().getAttribute(xaResourceRecord, "BranchQualifier");
if (Arrays.equals(failedResourceXid.getGlobalTransactionId(), (byte[]) getGlobalTransactionId) && Arrays.equals(failedResourceXid.getBranchQualifier(), (byte[]) getBranchQualifier)) {
Object getHeuristicValue = JMXServer.getAgent().getServer().getAttribute(xaResourceRecord, "HeuristicValue");
assertTrue(getHeuristicValue.equals(new Integer(6)));
JMXServer.getAgent().getServer().invoke(xaResourceRecord, "clearHeuristic", null, null);
}
}
XARecoveryModule xaRecoveryModule = new XARecoveryModule();
xaRecoveryModule.addXAResourceRecoveryHelper(new XAResourceRecoveryHelper() {
@Override
public boolean initialise(String p) throws Exception {
return false;
}
@Override
public XAResource[] getXAResources() throws Exception {
return new XAResource[] { new TestXAResource() {
public Xid[] recover(int var) throws XAException {
if (var == XAResource.TMSTARTRSCAN) {
if (failedResourceXid != null) {
return new Xid[] { failedResourceXid };
}
}
return new Xid[0];
}
@Override
public void commit(Xid xid, boolean b) throws XAException {
failedResourceXid = null;
}
@Override
public int prepare(Xid xid) throws XAException {
return 0;
}
@Override
public void rollback(Xid xid) throws XAException {
fail("Resource was rolled back");
}
} };
}
});
xaRecoveryModule.periodicWorkFirstPass();
Field safetyIntervalMillis = RecoveryXids.class.getDeclaredField("safetyIntervalMillis");
safetyIntervalMillis.setAccessible(true);
Object o1 = safetyIntervalMillis.get(null);
safetyIntervalMillis.set(null, 0);
try {
xaRecoveryModule.periodicWorkSecondPass();
} finally {
safetyIntervalMillis.set(null, o1);
}
xa.recover(XAResource.TMSTARTRSCAN);
try {
xa.commit(xid, false);
Assert.fail("Expecting XAException being thrown indicating more recover to be called");
} catch (XAException expected) {
Assert.assertTrue("On commit XAException error code indicating more recover call is expected but it's " + expected.errorCode, XAException.XA_RETRY == expected.errorCode || XAException.XAER_RMFAIL == expected.errorCode);
} finally {
xa.recover(XAResource.TMENDRSCAN);
}
assertNull(failedResourceXid);
}
use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction in project narayana by jbosstm.
the class XATerminatorImpleUnitTest method testConcurrentImport.
@Test
public void testConcurrentImport() throws Exception {
AtomicInteger completionCount = new AtomicInteger(0);
XidImple xid = new XidImple(new Uid());
final int TASK_COUNT = 400;
final int THREAD_COUNT = 200;
final CyclicBarrier gate = new CyclicBarrier(THREAD_COUNT + 1);
ArrayList<CompletableFuture<SubordinateTransaction>> futures = new ArrayList<>();
ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
for (int i = 0; i < TASK_COUNT; i++) futures.add(doAsync(completionCount, gate, i < THREAD_COUNT, executor, xid));
gate.await();
SubordinateTransaction prevStx = null;
for (CompletableFuture<SubordinateTransaction> future : futures) {
SubordinateTransaction stx = future.get();
if (stx == null) {
fail("transaction import returned null for future ");
} else {
if (prevStx != null)
assertEquals("transaction import for same xid returned a different instance", stx, prevStx);
else
prevStx = stx;
}
}
assertEquals("some transaction import futures did not complete", completionCount.get(), TASK_COUNT);
}
use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction in project narayana by jbosstm.
the class ImportedTransactionRecoveryUnitTest method testMultipleXAResourceForImportedJcaTransaction.
/**
* <p>
* Testing that multiple {@link XAResource}s could be used under imported transaction.<br>
* Previously there was no check of xid format which resulted to fact of merging usage of multiple XAResources
* under one Xid even when the subordinate transaction was under management of Narayana (meaning created by Narayana).
* That could lead to non-recoverable behavior for particular XAResource.
* <p>
* By adding check for format of xid Narayana generates new Xid for any XAResource used under transaction
* created by Narayana. If transaction comes from EIS there is returned the same Xid (as expected).
*/
@Test
public void testMultipleXAResourceForImportedJcaTransaction() throws Exception {
final Xid xid = XidUtils.getXid(new Uid(), true);
SubordinateTransaction subordinateTransaction = SubordinationManager.getTransactionImporter().importTransaction(xid);
TestXAResourceWrapper xar1 = new TestXAResourceWrapper("narayana", "narayana", "java:/test1") {
boolean wasThrown = false;
@Override
public void commit(Xid xid, boolean onePhase) throws XAException {
if (!wasThrown) {
wasThrown = true;
throw new XAException(XAException.XAER_RMFAIL);
} else {
super.commit(xid, onePhase);
}
}
};
TestXAResourceWrapper xar2 = new TestXAResourceWrapper("narayana", "narayana", "java:/test2") {
boolean wasThrown = false;
@Override
public void commit(Xid xid, boolean onePhase) throws XAException {
if (!wasThrown) {
wasThrown = true;
throw new XAException(XAException.XAER_RMFAIL);
} else {
super.commit(xid, onePhase);
}
}
};
assertTrue("Fail to enlist first test XAResource", subordinateTransaction.enlistResource(xar1));
assertTrue("Fail to enlist second XAResource", subordinateTransaction.enlistResource(xar2));
assertEquals("transaction should be prepared", TwoPhaseOutcome.PREPARE_OK, subordinateTransaction.doPrepare());
assertFalse("first resource should fail on transaction commit, thus whole txn can't be committed", subordinateTransaction.doCommit());
assertNotEquals("XAResources should be enlisted with different xids", xar1.getXid(), xar2.getXid());
((XARecoveryModule) recoveryManager.getModules().get(0)).addXAResourceRecoveryHelper(new TestXARecoveryHelper(xar1, xar2));
recoveryManager.scan();
assertEquals("XAResource1 can't be rolled-back", 0, xar1.rollbackCount());
assertEquals("XAResource2 can't be rolled-back", 0, xar2.rollbackCount());
assertEquals("XAResource1 has to be committed", 1, xar1.commitCount());
assertEquals("XAResource2 has to be committed", 1, xar2.commitCount());
}
use of com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction in project narayana by jbosstm.
the class SubordinateTestCase method testOnePhaseCommitSync.
// ///////////
@Test
public void testOnePhaseCommitSync() throws Exception {
final SubordinateTransaction tm = createTransaction();
final TestSynchronization sync = new TestSynchronization();
tm.registerSynchronization(sync);
tm.doOnePhaseCommit();
assertTrue(sync.isBeforeCompletionDone());
assertTrue(sync.isAfterCompletionDone());
assertEquals(javax.transaction.Status.STATUS_COMMITTED, tm.getStatus());
}
Aggregations