[jboss-svn-commits] JBL Code SVN: r38238 - in labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310: ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator and 4 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Oct 30 14:19:26 EDT 2012
Author: mmusgrov
Date: 2012-10-30 14:19:25 -0400 (Tue, 30 Oct 2012)
New Revision: 38238
Added:
labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseCommitThreadPool.java
labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jta/
labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jta/XAResourceRecord.java
Modified:
labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoordinatorEnvironmentBean.java
labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/AsyncCommit.java
labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/AsyncPrepare.java
labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java
labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java
labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java
Log:
JBTM-1310 Performance improvements (asynchronous prepare and in-lined JTS participant records)
Modified: labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoordinatorEnvironmentBean.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoordinatorEnvironmentBean.java 2012-10-30 15:10:36 UTC (rev 38237)
+++ labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoordinatorEnvironmentBean.java 2012-10-30 18:19:25 UTC (rev 38238)
@@ -42,6 +42,8 @@
private volatile boolean maintainHeuristics = true;
private volatile boolean transactionLog = false; // rename to useTransactionLog ?
+ private volatile int maxTwoPhaseCommitThreads = 100;
+
// public static final String TRANSACTION_LOG_REMOVAL_MARKER = "com.arjuna.ats.arjuna.coordinator.transactionLog.removalMarker";
//private String removalMarker;
@@ -146,6 +148,14 @@
this.asyncRollback = asyncRollback;
}
+ public int getMaxTwoPhaseCommitThreads() {
+ return maxTwoPhaseCommitThreads;
+ }
+
+ public void setMaxTwoPhaseCommitThreads(int maxTwoPhaseCommitThreads) {
+ this.maxTwoPhaseCommitThreads = maxTwoPhaseCommitThreads;
+ }
+
/**
* Returns true if one phase commit optimization is to be used.
*
Modified: labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/AsyncCommit.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/AsyncCommit.java 2012-10-30 15:10:36 UTC (rev 38237)
+++ labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/AsyncCommit.java 2012-10-30 18:19:25 UTC (rev 38238)
@@ -33,6 +33,8 @@
import com.arjuna.ats.internal.arjuna.thread.ThreadActionData;
+import java.util.concurrent.Callable;
+
/**
* This class is responsible for performing asynchronous termination of
* a transaction. Despite its name, it is also able to perform
@@ -48,32 +50,10 @@
* Default visibility.
*/
-class AsyncCommit extends Thread
+class AsyncCommit implements Runnable
{
-
- /**
- * Create a new instance, and give it the transaction to
- * control. The commit parameter determines whether the thread
- * should commit or rollback the transaction.
- */
-
-public static AsyncCommit create (BasicAction toControl, boolean commit)
+ public void run() {
{
- AsyncCommit c = new AsyncCommit(toControl, commit);
-
- c.start();
-
- Thread.yield();
-
- return c;
- }
-
- /**
- * Overloads Thread.run
- */
-
-public void run ()
- {
if (_theAction != null)
{
/*
@@ -95,12 +75,15 @@
ThreadActionData.popAction(false);
}
}
+ }
+
/**
- * The actual constructor for a new instance.
+ * Create a new instance, and give it the transaction to
+ * control. The commit parameter determines whether the thread
+ * should commit or rollback the transaction.
*/
-
-protected AsyncCommit (BasicAction toControl, boolean commit)
+ AsyncCommit (BasicAction toControl, boolean commit)
{
_theAction = toControl;
_commit = commit;
@@ -146,4 +129,4 @@
private BasicAction _theAction;
private boolean _commit;
-};
+}
Modified: labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/AsyncPrepare.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/AsyncPrepare.java 2012-10-30 15:10:36 UTC (rev 38237)
+++ labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/AsyncPrepare.java 2012-10-30 18:19:25 UTC (rev 38238)
@@ -33,6 +33,8 @@
import com.arjuna.ats.internal.arjuna.thread.ThreadActionData;
+import java.util.concurrent.Callable;
+
/**
* Instances of this class are responsible for performing asynchronous
* prepare on a specific AbstractRecord associated with a transaction.
@@ -45,56 +47,33 @@
/*
* Default visibility.
*/
+class AsyncPrepare implements Callable<Integer> {
+ public Integer call() throws Exception {
+ /*
+ * This is a transient thread so we don't want to register it
+ * with the action it is preparing, only change its notion of
+ * the current transaction so that any abstract records that
+ * need that information can still have it.
+ */
-class AsyncPrepare extends Thread
-{
+ ThreadActionData.pushAction(_theAction, false);
-public static AsyncPrepare create (BasicAction act, boolean reportHeuristics,
- AbstractRecord rec)
- {
- return new AsyncPrepare(act, reportHeuristics, rec);
- }
-
-public void run ()
- {
- if (_theAction != null)
- {
- /*
- * This is a transient thread so we don't
- * want to register it with the action it is
- * preparing, only change its notion of the
- * current transaction so that any abstract
- * records that need that information can still
- * have it.
- */
+ _outcome = _theAction.doPrepare(_reportHeuristics, _theRecord);
- ThreadActionData.pushAction(_theAction, false);
-
- _outcome = _theAction.doPrepare(_reportHeuristics, _theRecord);
+ ThreadActionData.popAction(false);
- ThreadActionData.popAction(false);
- }
-
- _theRecord = null;
- _theAction = null;
+ return _outcome;
}
-public int outcome ()
- {
- return _outcome;
+ protected AsyncPrepare(BasicAction act, boolean reportHeuristics, AbstractRecord rec) {
+ _theAction = act;
+ _outcome = TwoPhaseOutcome.PREPARE_NOTOK;
+ _reportHeuristics = reportHeuristics;
+ _theRecord = rec;
}
-
-protected AsyncPrepare (BasicAction act, boolean reportHeuristics, AbstractRecord rec)
- {
- _theAction = act;
- _outcome = TwoPhaseOutcome.PREPARE_NOTOK;
- _reportHeuristics = reportHeuristics;
- _theRecord = rec;
- }
-private BasicAction _theAction;
-private int _outcome;
-private boolean _reportHeuristics;
-private AbstractRecord _theRecord;
-
+ private BasicAction _theAction;
+ private int _outcome;
+ private boolean _reportHeuristics;
+ private AbstractRecord _theRecord;
};
Modified: labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java 2012-10-30 15:10:36 UTC (rev 38237)
+++ labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java 2012-10-30 18:19:25 UTC (rev 38238)
@@ -32,9 +32,13 @@
package com.arjuna.ats.arjuna.coordinator;
import java.io.IOException;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import com.arjuna.ats.arjuna.ObjectType;
import com.arjuna.ats.arjuna.StateManager;
@@ -596,7 +600,7 @@
if (actionStatus <= ActionStatus.ABORTING)
{
if (_childThreads == null)
- _childThreads = new Hashtable();
+ _childThreads = new Hashtable<String, Thread>();
_childThreads.put(ThreadUtil.getThreadId(t), t); // makes sure so we don't get
// duplicates
@@ -699,7 +703,7 @@
if (actionStatus <= ActionStatus.ABORTING)
{
if (_childActions == null)
- _childActions = new Hashtable();
+ _childActions = new Hashtable<BasicAction, BasicAction>();
_childActions.put(act, act);
result = true;
@@ -1281,7 +1285,7 @@
if (size > 0)
{
- Collection c = _childActions.values();
+ Collection<BasicAction> c = _childActions.values();
return c.toArray();
}
@@ -1482,7 +1486,7 @@
if (!reportHeuristics && TxControl.asyncCommit
&& (parentAction == null)) {
- AsyncCommit.create(this, false);
+ TwoPhaseCommitThreadPool.submitJob(new AsyncCommit(this, false));
} else
phase2Abort(reportHeuristics); /* first phase failed */
}
@@ -1491,7 +1495,7 @@
if (!reportHeuristics && TxControl.asyncCommit
&& (parentAction == null))
{
- AsyncCommit.create(this, true);
+ TwoPhaseCommitThreadPool.submitJob(new AsyncCommit(this, true));
}
else
phase2Commit(reportHeuristics); /* first phase succeeded */
@@ -1941,6 +1945,36 @@
}
}
+ protected int async_prepare(boolean reportHeuristics) {
+ int p = TwoPhaseOutcome.PREPARE_OK;
+ AbstractRecord lastRec = pendingList.getRear();
+ Collection<Future<Integer>> tasks = new ArrayList<Future<Integer>>();
+
+ while (pendingList.size() != 0)
+ tasks.add(TwoPhaseCommitThreadPool.submitJob(new AsyncPrepare(
+ this, reportHeuristics, pendingList.getFront())));
+
+ // prepare the last (or only) participant on the callers thread
+ if (lastRec != null)
+ p = doPrepare(reportHeuristics, lastRec);
+
+ // get the results
+ for (Future<Integer> task : tasks) {
+ try {
+ int outcome = task.get();
+
+ if (p == TwoPhaseOutcome.PREPARE_OK)
+ p = outcome;
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return p;
+ }
+
/**
* Phase one of a two phase commit protocol. This function returns the
* ouctome of the prepare operation. If all goes well it will be PREPARE_OK,
@@ -2011,66 +2045,7 @@
if ((actionType == ActionType.TOP_LEVEL) && (TxControl.asyncPrepare))
{
- int numberOfThreads = ((pendingList != null) ? pendingList.size()
- : 0);
- Thread[] threads = new Thread[numberOfThreads];
- int i;
-
- /*
- * First create them in a suspended way, so that we can purge the
- * list before it is added to (in the event of failures!)
- */
-
- for (i = 0; i < numberOfThreads; i++)
- {
- threads[i] = AsyncPrepare.create(this, reportHeuristics, pendingList.getFront());
- }
-
- /*
- * Now start the threads running.
- */
-
- for (i = 0; i < numberOfThreads; i++)
- {
- threads[i].start();
- Thread.yield();
- }
-
- /*
- * If one of these threads fails (PREPARE_NOTOK) do we terminate the
- * others or simply let them finish? Currently we wait and let them
- * all terminate regardless.
- */
-
- /*
- * Now synchronise with the threads.
- */
-
- for (int j = 0; j < numberOfThreads; j++)
- {
- while (threads[j].isAlive())
- {
- try
- {
- threads[j].join();
- }
- catch (Exception e)
- {
- tsLogger.logger.warn(e);
-
- p = TwoPhaseOutcome.PREPARE_NOTOK;
- }
- }
-
- /*
- * Only set the outcome if the current value is PREPARE_OK.
- */
-
- if (p == TwoPhaseOutcome.PREPARE_OK)
- p = ((AsyncPrepare) threads[j]).outcome();
-
- threads[j] = null;
- }
+ p = async_prepare(reportHeuristics);
}
else
{
@@ -3250,7 +3225,7 @@
{
problem = true;
- Enumeration iter = _childActions.elements();
+ Enumeration<BasicAction> iter = _childActions.elements();
BasicAction child = null;
boolean printError = true;
@@ -3265,7 +3240,7 @@
while (iter.hasMoreElements())
{
- child = (BasicAction) iter.nextElement();
+ child = iter.nextElement();
if (child.status() != ActionStatus.ABORTED) {
if (printError) {
@@ -3322,12 +3297,12 @@
* action.
*/
- Enumeration iter = _childThreads.elements();
+ Enumeration<Thread> iter = _childThreads.elements();
Thread t = null;
while (iter.hasMoreElements())
{
- t = (Thread) iter.nextElement();
+ t = iter.nextElement();
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("BasicAction::removeAllChildThreads () action "+get_uid()+" removing "+t);
@@ -3565,8 +3540,8 @@
* provide an explicit means of registering threads with an action.
*/
- private Hashtable _childThreads;
- private Hashtable _childActions;
+ private Hashtable<String, Thread> _childThreads;
+ private Hashtable<BasicAction, BasicAction> _childActions;
private BasicActionFinalizer finalizerObject;
private static final boolean finalizeBasicActions = arjPropertyManager.getCoordinatorEnvironmentBean().isFinalizeBasicActions();
Added: labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseCommitThreadPool.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseCommitThreadPool.java (rev 0)
+++ labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseCommitThreadPool.java 2012-10-30 18:19:25 UTC (rev 38238)
@@ -0,0 +1,22 @@
+package com.arjuna.ats.arjuna.coordinator;
+
+import com.arjuna.ats.arjuna.common.arjPropertyManager;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+public class TwoPhaseCommitThreadPool {
+ private static final int poolSize = arjPropertyManager.getCoordinatorEnvironmentBean().
+ getMaxTwoPhaseCommitThreads();
+ private static final ExecutorService executor = Executors.newFixedThreadPool(poolSize);
+
+ public static Future<Integer> submitJob(Callable<Integer> job) {
+ return executor.submit(job);
+ }
+
+ public static void submitJob(Runnable job) {
+ executor.submit(job);
+ }
+}
Modified: labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java 2012-10-30 15:10:36 UTC (rev 38237)
+++ labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java 2012-10-30 18:19:25 UTC (rev 38238)
@@ -1195,7 +1195,7 @@
* with the thread, i.e., has end already been called on it?
*/
- private final boolean endAssociation()
+ protected boolean endAssociation()
{
boolean doEnd = true;
Added: labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jta/XAResourceRecord.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jta/XAResourceRecord.java (rev 0)
+++ labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jta/XAResourceRecord.java 2012-10-30 18:19:25 UTC (rev 38238)
@@ -0,0 +1,59 @@
+package com.arjuna.ats.internal.jta.resources.jta;
+
+import com.arjuna.ats.internal.jta.transaction.jts.TransactionImple;
+import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
+import com.arjuna.ats.internal.jta.xa.TxInfo;
+import com.arjuna.ats.jta.logging.jtaLogger;
+
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+public class XAResourceRecord extends
+ com.arjuna.ats.internal.jta.resources.arjunacore.XAResourceRecord {
+
+ private TransactionImple _tx;
+
+ public XAResourceRecord(TransactionImple tx, XAResource res, Xid xid,
+ Object[] params) {
+ super(null, res, xid, params);
+
+ }
+
+ public int topLevelAbort()
+ {
+ if (jtaLogger.logger.isTraceEnabled()) {
+ jtaLogger.logger.trace("XAResourceRecord.topLevelAbort for " + this);
+ }
+
+ if (_tx != null
+ && _tx.getXAResourceState(_theXAResource) == TxInfo.OPTIMIZED_ROLLBACK)
+ {
+ /*
+ * Already rolledback during delist.
+ */
+
+ return TwoPhaseOutcome.FINISH_OK;
+ } else {
+ return super.topLevelAbort();
+ }
+ }
+
+ protected boolean endAssociation()
+ {
+ boolean doEnd = true;
+
+ if (_tx != null)
+ {
+ if (_tx.getXAResourceState(_theXAResource) == TxInfo.NOT_ASSOCIATED)
+ {
+ // end has been called so we don't need to do it again!
+
+ doEnd = false;
+ }
+ }
+ else
+ doEnd = false; // Recovery mode
+
+ return doEnd;
+ }
+}
Modified: labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java 2012-10-30 15:10:36 UTC (rev 38237)
+++ labs/jbosstm/branches/JBOSSTS_4_16_4_Final_JBTM-1310/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java 2012-10-30 18:19:25 UTC (rev 38238)
@@ -45,6 +45,8 @@
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
+import com.arjuna.ats.arjuna.coordinator.AddOutcome;
+import com.arjuna.ats.internal.jta.resources.arjunacore.XAOnePhaseResource;
import org.omg.CORBA.INVALID_TRANSACTION;
import org.omg.CORBA.TRANSACTION_ROLLEDBACK;
import org.omg.CORBA.TRANSACTION_UNAVAILABLE;
@@ -707,7 +709,8 @@
}
catch (XAException te)
{
- jtaxLogger.i18NLogger.warn_jtax_transaction_jts_timeouterror("TransactionImple.enlistResource",
+ jtaxLogger.i18NLogger.warn_jtax_transaction_jts_timeouterror(
+ "TransactionImple.enlistResource",
XAHelper.printXAErrorCode(te), XAHelper.xidToString(xid), te);
}
}
@@ -722,21 +725,47 @@
// The xid will change on each pass of the loop, so we need to create a new record on each pass.
// The registerResource will fail in the case of multiple last resources being disallowed.
// see JBTM-362 and JBTM-363
- XAResourceRecord xaResourceRecord = createRecord(xaRes, params, xid);
- if(xaResourceRecord != null) {
+ TwoPhaseCoordinator theTx = (TwoPhaseCoordinator) BasicAction.Current();
+
+ if (theTx != null) {
+ int result;
+
xaRes.start(xid, XAResource.TMNOFLAGS);
- try {
- RecoveryCoordinator recCoord = _theTransaction.registerResource(xaResourceRecord.getResource());
- xaResourceRecord.setRecoveryCoordinator(recCoord);
- } catch(Exception e) {
- // we called start on the resource, but _theTransaction did not accept it.
- // we therefore have a mess which we must now clean up by ensuring the start is undone:
- xaResourceRecord.rollback();
- markRollbackOnly();
- return false;
+ if ((xaRes instanceof LastResourceCommitOptimisation)
+ || ((LAST_RESOURCE_OPTIMISATION_INTERFACE != null) &&
+ LAST_RESOURCE_OPTIMISATION_INTERFACE.isInstance(xaRes))) {
+ result = theTx.add(
+ new com.arjuna.ats.internal.arjuna.abstractrecords.LastResourceRecord(
+ new XAOnePhaseResource(xaRes, xid, params)));
+ } else {
+ result = theTx.add(new com.arjuna.ats.internal.jta.resources.jta.XAResourceRecord(
+ this, xaRes, xid, params));
}
- _resources.put(xaRes, new TxInfo(xid));
- return true; // dive out, no need to set associatedWork = true;
+
+ if (result != AddOutcome.AR_ADDED) {
+ // we called start on the resource, but _theTransaction did not accept it. We
+ // therefore have a mess which we must now clean up by ensuring the start is undone:
+ xaRes.rollback(xid);
+ } else {
+ _resources.put(xaRes, new TxInfo(xid));
+ return true; // dive out, no need to set associatedWork = true;
+ }
+ } else {
+ XAResourceRecord xaResourceRecord = createRecord(xaRes, params, xid);
+ if(xaResourceRecord != null) {
+ xaRes.start(xid, XAResource.TMNOFLAGS);
+ try {
+ RecoveryCoordinator recCoord = _theTransaction.registerResource(
+ xaResourceRecord.getResource());
+ xaResourceRecord.setRecoveryCoordinator(recCoord);
+ _resources.put(xaRes, new TxInfo(xid));
+ return true; // dive out, no need to set associatedWork = true;
+ } catch(Exception e) {
+ // we called start on the resource, but _theTransaction did not accept it. We
+ // therefore have a mess which we must now clean up by ensuring the start is undone:
+ xaResourceRecord.rollback();
+ }
+ }
}
// if we get to here, something other than a failure of xaRes.start probably went wrong.
@@ -772,7 +801,8 @@
* rollback only.
*/
- jtaxLogger.i18NLogger.warn_jtax_transaction_jts_starterror("TransactionImple.enlistResource - XAResource.start",
+ jtaxLogger.i18NLogger.warn_jtax_transaction_jts_starterror(
+ "TransactionImple.enlistResource - XAResource.start",
XAHelper.printXAErrorCode(e), XAHelper.xidToString(xid), e);
markRollbackOnly();
@@ -782,7 +812,8 @@
if (retry < 0)
{
- jtaxLogger.i18NLogger.warn_jtax_transaction_jts_starterror("TransactionImple.enlistResource - XAResource.start",
+ jtaxLogger.i18NLogger.warn_jtax_transaction_jts_starterror(
+ "TransactionImple.enlistResource - XAResource.start",
XAHelper.printXAErrorCode(e), XAHelper.xidToString(xid), e);
markRollbackOnly();
@@ -813,7 +844,8 @@
}
catch (XAException ex)
{
- jtaxLogger.i18NLogger.warn_jtax_transaction_jts_xaerror("TransactionImple.enlistResource - xa_start: ", XAHelper.printXAErrorCode(ex), ex);
+ jtaxLogger.i18NLogger.warn_jtax_transaction_jts_xaerror(
+ "TransactionImple.enlistResource - xa_start: ", XAHelper.printXAErrorCode(ex), ex);
markRollbackOnly();
@@ -1049,7 +1081,8 @@
markRollbackOnly();
- jtaxLogger.i18NLogger.warn_jtax_transaction_jts_xaerror("TransactionImple.delistResource", XAHelper.printXAErrorCode(exp), exp);
+ jtaxLogger.i18NLogger.warn_jtax_transaction_jts_xaerror("TransactionImple.delistResource",
+ XAHelper.printXAErrorCode(exp), exp);
return false;
}
More information about the jboss-svn-commits
mailing list