[jboss-svn-commits] JBL Code SVN: r37633 - in labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration: examples/classes/com/arjuna/jta/distributed/example/server/impl and 3 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Oct 20 09:47:11 EDT 2011
Author: tomjenkinson
Date: 2011-10-20 09:47:11 -0400 (Thu, 20 Oct 2011)
New Revision: 37633
Added:
labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/byteman-scripts/leaverunningorphan.txt
Modified:
labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/examples/classes/com/arjuna/jta/distributed/example/server/RemoteServer.java
labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/examples/classes/com/arjuna/jta/distributed/example/server/impl/ServerImpl.java
labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/classes/com/arjuna/ats/jta/distributed/SimpleIsolatedServers.java
labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/classes/com/arjuna/ats/jta/distributed/server/impl/ServerImpl.java
Log:
JBTM-895 recover inflight subordinate transactions
Modified: labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/examples/classes/com/arjuna/jta/distributed/example/server/RemoteServer.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/examples/classes/com/arjuna/jta/distributed/example/server/RemoteServer.java 2011-10-20 13:44:52 UTC (rev 37632)
+++ labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/examples/classes/com/arjuna/jta/distributed/example/server/RemoteServer.java 2011-10-20 13:47:11 UTC (rev 37633)
@@ -43,7 +43,9 @@
/**
* Atypical for a recover call we need to pass over the node name of the
* caller. This will ensure that all Xids for the caller coordinated
- * Subordinates are returned.
+ * Subordinates are returned. Also this method should pass true to the
+ * XATerminator::recover method so that it will recover the inflight
+ * transactions for this node
*
* @param callingServerNodeName
* @return
Modified: labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/examples/classes/com/arjuna/jta/distributed/example/server/impl/ServerImpl.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/examples/classes/com/arjuna/jta/distributed/example/server/impl/ServerImpl.java 2011-10-20 13:44:52 UTC (rev 37632)
+++ labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/examples/classes/com/arjuna/jta/distributed/example/server/impl/ServerImpl.java 2011-10-20 13:47:11 UTC (rev 37633)
@@ -276,7 +276,8 @@
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
- Xid[] recovered = ((XATerminatorImple) SubordinationManager.getXATerminator()).doRecover(parentNodeName);
+ // Pass in true so we can recover the inflight transactions for this node
+ Xid[] recovered = ((XATerminatorImple) SubordinationManager.getXATerminator()).doRecover(parentNodeName, true);
return recovered;
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
Added: labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/byteman-scripts/leaverunningorphan.txt
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/byteman-scripts/leaverunningorphan.txt (rev 0)
+++ labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/byteman-scripts/leaverunningorphan.txt 2011-10-20 13:47:11 UTC (rev 37633)
@@ -0,0 +1,18 @@
+########################################################################
+#
+# byteman script used to ensure that tests can synchronize with various
+# actions performed by the recovery code
+
+#########################################################################
+
+RULE Fail resource prepare finishing
+CLASS com.arjuna.ats.jta.distributed.SimpleIsolatedServers
+METHOD performTransactionalWork
+AT EXIT
+BIND NOTHING
+IF TRUE
+ DO debug("Neutralizing target"),
+ Thread.currentThread().stop()
+ENDRULE
+
+
Modified: labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/classes/com/arjuna/ats/jta/distributed/SimpleIsolatedServers.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/classes/com/arjuna/ats/jta/distributed/SimpleIsolatedServers.java 2011-10-20 13:44:52 UTC (rev 37632)
+++ labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/classes/com/arjuna/ats/jta/distributed/SimpleIsolatedServers.java 2011-10-20 13:47:11 UTC (rev 37633)
@@ -87,6 +87,21 @@
}
}
+ private static void reboot(Integer serverName) throws Exception {
+ int index = (serverName / 1000) - 1;
+ ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(localServers[index].getClass().getClassLoader());
+ localServers[index].shutdown();
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+
+ IsolatableServersClassLoader classLoader = new IsolatableServersClassLoader("com.arjuna.ats.jta.distributed.server", contextClassLoader);
+ localServers[index] = (LocalServer) classLoader.loadClass("com.arjuna.ats.jta.distributed.server.impl.ServerImpl").newInstance();
+ Thread.currentThread().setContextClassLoader(localServers[index].getClass().getClassLoader());
+ localServers[index].initialise(lookupProvider, (index + 1) * 1000);
+ remoteServers[index] = localServers[index].connectTo();
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+ }
+
/**
* The JCA XATerminator call wont allow intermediary calls to
* XATerminator::recover between TMSTARTSCAN and TMENDSCAN. This is fine for
@@ -336,6 +351,107 @@
}
@Test
+ @BMScript("leaverunningorphan")
+ public void testRecoverInflightTransaction() throws Exception {
+ final CompletionCounter counter = new CompletionCounter() {
+ private int commitCount = 0;
+ private int rollbackCount = 0;
+
+ @Override
+ public void incrementCommit() {
+ commitCount++;
+
+ }
+
+ @Override
+ public void incrementRollback() {
+ rollbackCount++;
+ }
+
+ @Override
+ public int getCommitCount() {
+ return commitCount;
+ }
+
+ @Override
+ public int getRollbackCount() {
+ return rollbackCount;
+ }
+
+ @Override
+ public void resetCounters() {
+ commitCount = 0;
+ rollbackCount = 0;
+ }
+ };
+
+ assertTrue(getLocalServer(3000).getCompletionCounter().getCommitCount() == 0);
+ assertTrue(getLocalServer(2000).getCompletionCounter().getCommitCount() == 0);
+ assertTrue(getLocalServer(1000).getCompletionCounter().getCommitCount() == 0);
+ final Phase2CommitAborted phase2CommitAborted = new Phase2CommitAborted();
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ int startingTimeout = 0;
+ try {
+ int startingServer = 1000;
+ LocalServer originalServer = getLocalServer(startingServer);
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(originalServer.getClass().getClassLoader());
+ TransactionManager transactionManager = originalServer.getTransactionManager();
+ transactionManager.setTransactionTimeout(startingTimeout);
+ transactionManager.begin();
+ Transaction originalTransaction = transactionManager.getTransaction();
+ int remainingTimeout = (int) (originalServer.getTimeLeftBeforeTransactionTimeout() / 1000);
+ Xid currentXid = originalServer.getCurrentXid();
+ originalServer.storeRootTransaction();
+ XAResource proxyXAResource = originalServer.generateProxyXAResource(lookupProvider, 2000);
+ transactionManager.suspend();
+ performTransactionalWork(counter, new LinkedList<Integer>(Arrays.asList(new Integer[] { 2000 })), remainingTimeout, currentXid, 2, false);
+ transactionManager.resume(originalTransaction);
+ originalTransaction.enlistResource(proxyXAResource);
+ originalServer.removeRootTransaction(currentXid);
+ transactionManager.commit();
+ Thread.currentThread().setContextClassLoader(classLoader);
+ } catch (ExecuteException e) {
+ System.err.println("Should be a thread death but cest la vie");
+ synchronized (phase2CommitAborted) {
+ phase2CommitAborted.setPhase2CommitAborted(true);
+ phase2CommitAborted.notify();
+ }
+ } catch (LinkageError t) {
+ System.err.println("Should be a thread death but cest la vie");
+ synchronized (phase2CommitAborted) {
+ phase2CommitAborted.setPhase2CommitAborted(true);
+ phase2CommitAborted.notify();
+ }
+ } catch (Throwable t) {
+ System.err.println("Should be a thread death but cest la vie");
+ synchronized (phase2CommitAborted) {
+ phase2CommitAborted.setPhase2CommitAborted(true);
+ phase2CommitAborted.notify();
+ }
+ }
+ }
+ }, "Orphan-creator");
+ thread.start();
+ synchronized (phase2CommitAborted) {
+ if (!phase2CommitAborted.isPhase2CommitAborted()) {
+ phase2CommitAborted.wait();
+ }
+ }
+ reboot(1000);
+ assertTrue(counter.getCommitCount() == 0);
+ assertTrue(counter.getRollbackCount() == 0);
+ assertTrue(getLocalServer(1000).getCompletionCounter().getCommitCount() == 0);
+ assertTrue(getLocalServer(1000).getCompletionCounter().getRollbackCount() == 0);
+ getLocalServer(1000).doRecoveryManagerScan(true);
+ assertTrue(getLocalServer(1000).getCompletionCounter().getCommitCount() == 0);
+ assertTrue(getLocalServer(1000).getCompletionCounter().getRollbackCount() == 1);
+ assertTrue(counter.getCommitCount() == 0);
+ assertTrue(counter.getRollbackCount() == 2);
+ }
+
+ @Test
@BMScript("fail2pc")
public void testRecovery() throws Exception {
tearDown();
Modified: labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/classes/com/arjuna/ats/jta/distributed/server/impl/ServerImpl.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/classes/com/arjuna/ats/jta/distributed/server/impl/ServerImpl.java 2011-10-20 13:44:52 UTC (rev 37632)
+++ labs/jbosstm/branches/JBOSSTS_4_15_0_Final/atsintegration/tests/classes/com/arjuna/ats/jta/distributed/server/impl/ServerImpl.java 2011-10-20 13:47:11 UTC (rev 37633)
@@ -384,7 +384,7 @@
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
- Xid[] recovered = ((XATerminatorImple) SubordinationManager.getXATerminator()).doRecover(parentNodeName);
+ Xid[] recovered = ((XATerminatorImple) SubordinationManager.getXATerminator()).doRecover(parentNodeName, true);
return recovered;
} finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
More information about the jboss-svn-commits
mailing list