[jboss-svn-commits] JBL Code SVN: r29095 - in labs/jbosstm/trunk: ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore and 6 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Aug 27 17:36:39 EDT 2009
Author: mark.little at jboss.com
Date: 2009-08-27 17:36:39 -0400 (Thu, 27 Aug 2009)
New Revision: 29095
Modified:
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseOutcome.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/XARecoveryModule.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/TransactionImple.java
labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/XAResourceRecord.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/SubordinateAtomicTransaction.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/TransactionImple.java
labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/ExtendedResourceRecord.java
Log:
https://jira.jboss.org/jira/browse/JBTM-605
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/BasicAction.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -2669,8 +2669,11 @@
criticalStart();
if ((heuristicList == null) && reportHeuristics)
- heuristicList = new RecordList(); // the only list we'll need.
-
+ heuristicList = new RecordList();
+
+ if (failedList == null)
+ failedList = new RecordList();
+
/*
* Since it is one-phase, the outcome from the record is the outcome of
* the transaction. Therefore, we don't need to save much intermediary
@@ -2680,10 +2683,10 @@
boolean stateToSave = false;
recordBeingHandled = pendingList.getFront();
-
+
int p = ((actionType == ActionType.TOP_LEVEL) ? recordBeingHandled.topLevelOnePhaseCommit()
: recordBeingHandled.nestedOnePhaseCommit());
-
+
if ((p == TwoPhaseOutcome.FINISH_OK)
|| (p == TwoPhaseOutcome.PREPARE_READONLY))
{
@@ -2701,73 +2704,70 @@
}
else
{
- // aborted or heuristic which we aren't interested in
-
if (p == TwoPhaseOutcome.FINISH_ERROR)
{
- /*
- * Don't bother about the failedList - we are aborting, and
- * there is only one record!
- */
-
- recordBeingHandled = null;
-
- actionStatus = ActionStatus.ABORTED;
+ if (!failedList.insert(recordBeingHandled))
+ recordBeingHandled = null;
+ else
+ {
+ if (!stateToSave)
+ stateToSave = recordBeingHandled.doSave();
+ }
}
else
{
- /*
- * Heuristic decision!!
- */
-
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- {
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.coordinator.BasicAction_47", new Object[]
- { get_uid(), TwoPhaseOutcome.stringForm(p) });
- }
-
- if (reportHeuristics)
- {
- updateHeuristic(p, true);
-
- if (!heuristicList.insert(recordBeingHandled))
- recordBeingHandled = null;
- else
- {
- if (!stateToSave)
- stateToSave = recordBeingHandled.doSave();
- }
- }
-
- if (heuristicDecision == TwoPhaseOutcome.HEURISTIC_ROLLBACK)
- {
- /*
- * Signal that the action outcome is the same as the
- * heuristic decision.
- */
-
- heuristicDecision = TwoPhaseOutcome.PREPARE_OK; // means no
- // heuristic
- // was
- // raised.
-
- actionStatus = ActionStatus.ABORTED;
- }
- else if (heuristicDecision == TwoPhaseOutcome.HEURISTIC_COMMIT)
- {
- heuristicDecision = TwoPhaseOutcome.PREPARE_OK;
- actionStatus = ActionStatus.COMMITTED;
- }
- else
- actionStatus = ActionStatus.COMMITTED; // can't really say
- // (could have
- // aborted)
- }
+ /*
+ * Heuristic decision!!
+ */
+
+ if (tsLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.coordinator.BasicAction_47", new Object[]
+ { get_uid(), TwoPhaseOutcome.stringForm(p) });
+ }
+
+ if (reportHeuristics)
+ {
+ updateHeuristic(p, true);
+
+ if (!heuristicList.insert(recordBeingHandled))
+ recordBeingHandled = null;
+ else
+ {
+ if (!stateToSave)
+ stateToSave = recordBeingHandled.doSave();
+ }
+ }
+
+ if (heuristicDecision == TwoPhaseOutcome.HEURISTIC_ROLLBACK)
+ {
+ /*
+ * Signal that the action outcome is the same as the
+ * heuristic decision.
+ */
+
+ heuristicDecision = TwoPhaseOutcome.PREPARE_OK; // means no
+ // heuristic
+ // was
+ // raised.
+
+ actionStatus = ActionStatus.ABORTED;
+ }
+ else if (heuristicDecision == TwoPhaseOutcome.HEURISTIC_COMMIT)
+ {
+ heuristicDecision = TwoPhaseOutcome.PREPARE_OK;
+ actionStatus = ActionStatus.COMMITTED;
+ }
+ else
+ actionStatus = ActionStatus.H_HAZARD; // can't really say
+ // (could have
+ // aborted)
+ }
}
if (actionType == ActionType.TOP_LEVEL)
{
- if (stateToSave && (heuristicList.size() > 0))
+ if (stateToSave && ((heuristicList.size() > 0) || (failedList.size() > 0)))
{
if (store() == null)
{
@@ -3227,7 +3227,7 @@
{
/*
* The commit failed. Add this record to the failed
- * list to indicate this.
+ * list to indicate this. Covers statuses like FAILED_ERROR.
*/
failedList.insert(recordBeingHandled);
@@ -3259,7 +3259,7 @@
}
}
- return TwoPhaseOutcome.FINISH_OK;
+ return ok;
}
/*
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseOutcome.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseOutcome.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseOutcome.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -48,6 +48,8 @@
* @since JTS 1.0.
*/
+// TODO this needs extending.
+
public class TwoPhaseOutcome
{
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/XARecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/XARecoveryModule.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/XARecoveryModule.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -447,6 +447,8 @@
{
if (recoveryStatus == XARecoveryResource.WAITING_FOR_RECOVERY)
{
+ // resource initiated recovery not possible (no distribution).
+
problem = false;
if (jtaLogger.loggerI18N
@@ -479,9 +481,7 @@
}
}
else
- problem = false; // resource initiated
- // recovery not possible
- // (no distribution).
+ problem = false;
}
break;
case XARecoveryResource.INFLIGHT_TRANSACTION:
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -51,6 +51,7 @@
import com.arjuna.ats.arjuna.ObjectType;
import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator;
import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
import com.arjuna.ats.arjuna.coordinator.RecordType;
import com.arjuna.ats.arjuna.coordinator.TxControl;
@@ -447,9 +448,9 @@
{
if (jtaLogger.loggerI18N.isWarnEnabled())
{
- jtaLogger.loggerI18N.warn(
- "com.arjuna.ats.internal.jta.resources.arjunacore.rollbackerror",
- new Object[] { _tranID, _theXAResource, XAHelper.printXAErrorCode(e1) }, e1);
+ jtaLogger.loggerI18N.warn(
+ "com.arjuna.ats.internal.jta.resources.arjunacore.rollbackerror",
+ new Object[] { _tranID, _theXAResource, XAHelper.printXAErrorCode(e1) }, e1);
}
switch (e1.errorCode)
@@ -483,12 +484,12 @@
}
catch (Exception e2)
{
- if (jtaLogger.loggerI18N.isWarnEnabled())
- {
- jtaLogger.loggerI18N.warn(
- "com.arjuna.ats.internal.jta.resources.arjunacore.rollbackerror",
- new Object[] { _tranID, _theXAResource, e2.toString() }, e2);
- }
+ if (jtaLogger.loggerI18N.isWarnEnabled())
+ {
+ jtaLogger.loggerI18N.warn(
+ "com.arjuna.ats.internal.jta.resources.arjunacore.rollbackerror",
+ new Object[] { _tranID, _theXAResource, e2.toString() }, e2);
+ }
return TwoPhaseOutcome.FINISH_ERROR;
}
@@ -591,9 +592,9 @@
{
if (jtaLogger.loggerI18N.isWarnEnabled())
{
- jtaLogger.loggerI18N.warn(
- "com.arjuna.ats.internal.jta.resources.arjunacore.commitxaerror",
- new Object[] { _tranID, _theXAResource, XAHelper.printXAErrorCode(e1) }, e1);
+ jtaLogger.loggerI18N.warn(
+ "com.arjuna.ats.internal.jta.resources.arjunacore.commitxaerror",
+ new Object[] { _tranID, _theXAResource, XAHelper.printXAErrorCode(e1) }, e1);
}
/*
@@ -611,7 +612,7 @@
// this code here.
break;
case XAException.XA_HEURRB:
- case XAException.XA_RBROLLBACK:
+ case XAException.XA_RBROLLBACK: // could really do with an ABORTED status in TwoPhaseOutcome to differentiate
case XAException.XA_RBCOMMFAIL:
case XAException.XA_RBDEADLOCK:
case XAException.XA_RBINTEGRITY:
@@ -630,6 +631,8 @@
return TwoPhaseOutcome.HEURISTIC_HAZARD; // something terminated the transaction!
case XAException.XAER_PROTO:
case XAException.XA_RETRY:
+ _committed = true; // will cause log to be rewritten
+
/*
* Could do timeout retry here, but that could cause other resources in the list to go down the
* heuristic path (some are far too keen to do this). Fail and let recovery retry. Meanwhile
@@ -648,14 +651,14 @@
}
catch (Exception e2)
{
- if (jtaLogger.loggerI18N.isWarnEnabled())
- {
- jtaLogger.loggerI18N.warn(
- "com.arjuna.ats.internal.jta.resources.arjunacore.commitxaerror",
- new Object[] { _tranID, _theXAResource, e2.toString() }, e2);
- }
+ if (jtaLogger.loggerI18N.isWarnEnabled())
+ {
+ jtaLogger.loggerI18N.warn(
+ "com.arjuna.ats.internal.jta.resources.arjunacore.commitxaerror",
+ new Object[] { _tranID, _theXAResource, e2.toString() }, e2);
+ }
- return TwoPhaseOutcome.FINISH_ERROR;
+ return TwoPhaseOutcome.FINISH_ERROR;
}
finally
{
@@ -880,16 +883,19 @@
case XAException.XA_RBTRANSIENT:
case XAException.XAER_RMERR:
forget();
- return TwoPhaseOutcome.FINISH_ERROR;
+ return TwoPhaseOutcome.HEURISTIC_ROLLBACK;
case XAException.XAER_NOTA:
return TwoPhaseOutcome.HEURISTIC_HAZARD; // something committed or rolled back without asking us!
- case XAException.XAER_PROTO:
- case XAException.XAER_INVAL:
- case XAException.XAER_RMFAIL: // resource manager failed,
- // did it rollback?
- return TwoPhaseOutcome.FINISH_ERROR;
+ case XAException.XAER_INVAL:
+ case XAException.XAER_RMFAIL: // resource manager
+ // failed, did it
+ // rollback?
+ return TwoPhaseOutcome.HEURISTIC_HAZARD;
+ case XAException.XA_RETRY:
+ case XAException.XAER_PROTO:
default:
- return TwoPhaseOutcome.FINISH_ERROR;
+ _committed = true; // will cause log to be rewritten
+ return TwoPhaseOutcome.FINISH_ERROR; // recovery should retry
}
}
catch (Exception e2)
@@ -961,7 +967,20 @@
"XAResourceRecord.recover");
}
- return XARecoveryResource.FAILED_TO_RECOVER;
+ if (_committed)
+ {
+ /*
+ * A previous commit attempt failed, but we know the intention
+ * was to commit. So let's try again.
+ */
+
+ if (topLevelCommit() == TwoPhaseOutcome.FINISH_OK)
+ return XARecoveryResource.RECOVERED_OK;
+ else
+ return XARecoveryResource.FAILED_TO_RECOVER;
+ }
+ else
+ return XARecoveryResource.WAITING_FOR_RECOVERY;
}
public static AbstractRecord create()
@@ -987,7 +1006,8 @@
try
{
os.packInt(_heuristic);
-
+ os.packBoolean(_committed);
+
/*
* Since we don't know what type of Xid we are using, leave it up to
* XID to pack.
@@ -1082,6 +1102,8 @@
try
{
_heuristic = os.unpackInt();
+ _committed = os.unpackBoolean();
+
_tranID = XidImple.unpack(os);
_theXAResource = null;
@@ -1367,6 +1389,8 @@
private int _heuristic;
+ private boolean _committed = false; // try to optimize recovery
+
private TransactionImple _theTransaction;
private boolean _recovered = false;
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/TransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/TransactionImple.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/TransactionImple.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -281,6 +281,7 @@
switch (status)
{
case ActionStatus.COMMITTED:
+ case ActionStatus.COMMITTING:
case ActionStatus.H_COMMIT:
TransactionImple.removeTransaction(this);
break;
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -505,17 +505,68 @@
assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
}
-/*
@Test
- public void testFailOnCommit() throws Exception
+ public void testFailOnCommitOnePhaseRetry () throws Exception
{
final Xid xid = new XidImple(new Uid());
final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
final TestXAResource xaResource = new TestXAResource();
+
+ xaResource.setCommitException(new XAException(XAException.XA_RETRY));
+
+ t.enlistResource(xaResource);
+
+ final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+
+ /*
+ * This should not cause problems. The transaction really has committed, or will once
+ * recovery kicks off. So nothing for the parent to do. The subordinate log will
+ * maintain enough information to drive recovery locally if we get to the point of
+ * issuing a commit call from parent to child.
+ */
+
+ xaTerminator.commit(xid, true); // transaction is completed (or will be eventually by recovery).
+ }
+
+ @Test
+ public void testFailOnCommitOnePhase () throws Exception
+ {
+ final Xid xid = new XidImple(new Uid());
+ final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
+
+ final TestXAResource xaResource = new TestXAResource();
// provoke commit into failing with TwoPhaseOutcome.FINISH_ERROR
// warning: this is sensitive to the impl exception handling in
// XAResourceRecord.topLevelCommit
+ xaResource.setCommitException(new XAException(XAException.XA_HEURRB)); // should cause an exception!
+
+ t.enlistResource(xaResource);
+
+ final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+
+ try
+ {
+ xaTerminator.commit(xid, true);
+ }
+ catch (final XAException ex)
+ {
+ // success!
+
+ return;
+ }
+
+ assertTrue("commit should throw an exception and not get to here", false);
+ }
+
+ @Test
+ public void testFailOnCommitRetry () throws Exception
+ {
+ final Xid xid = new XidImple(new Uid());
+ final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
+
+ final TestXAResource xaResource = new TestXAResource();
+
xaResource.setCommitException(new XAException(XAException.XA_RETRY));
t.enlistResource(xaResource);
@@ -523,11 +574,45 @@
final XATerminator xaTerminator = SubordinationManager.getXATerminator();
xaTerminator.prepare(xid);
+
+ /*
+ * This should not cause problems. The transaction really has committed, or will once
+ * recovery kicks off. So nothing for the parent to do. The subordinate log will
+ * maintain enough information to drive recovery locally if we get to the point of
+ * issuing a commit call from parent to child.
+ */
+
xaTerminator.commit(xid, false);
+ }
+
+ @Test
+ public void testFailOnCommit() throws Exception
+ {
+ final Xid xid = new XidImple(new Uid());
+ final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
- //assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
+ final TestXAResource xaResource = new TestXAResource();
+ // provoke commit into failing with TwoPhaseOutcome.FINISH_ERROR
+ // warning: this is sensitive to the impl exception handling in
+ // XAResourceRecord.topLevelCommit
+ xaResource.setCommitException(new XAException(XAException.XA_HEURHAZ)); // throw a little spice into things!
+ t.enlistResource(xaResource);
+
+ final XATerminator xaTerminator = SubordinationManager.getXATerminator();
+
+ try
+ {
+ xaTerminator.prepare(xid);
+ xaTerminator.commit(xid, false);
+ }
+ catch (final XAException ex)
+ {
+ // success!!
+
+ return;
+ }
+
assertTrue("commit should throw an exception and not get to here", false);
}
-*/
}
Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/XAResourceRecord.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/XAResourceRecord.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/XAResourceRecord.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -603,7 +603,8 @@
throw new TRANSACTION_ROLLEDBACK();
case XAException.XA_RETRY:
- throw new UNKNOWN();
+ _committed = true; // remember for recovery later.
+ throw new UNKNOWN(); // will cause log to be rewritten.
case XAException.XAER_INVAL:
case XAException.XAER_RMFAIL: // resource manager
// failed, did it
@@ -878,8 +879,11 @@
case XAException.XAER_INVAL:
case XAException.XAER_RMFAIL: // resource manager failed,
// did it rollback?
- throw new UNKNOWN();
+ throw new org.omg.CosTransactions.HeuristicHazard();
+ case XAException.XA_RETRY:
default:
+ _committed = true; // will cause log to be rewritten
+
throw new UNKNOWN();
}
}
@@ -957,7 +961,8 @@
try
{
os.packInt(_heuristic);
-
+ os.packBoolean(_committed);
+
/*
* Since we don't know what type of Xid we are using, leave it up to
* XID to pack.
@@ -1058,6 +1063,8 @@
try
{
_heuristic = os.unpackInt();
+ _committed = os.unpackBoolean();
+
_tranID = XidImple.unpack(os);
_theXAResource = null;
@@ -1253,8 +1260,11 @@
}
catch (OBJECT_NOT_EXIST ex)
{
- // no coordinator, so presumed abort.
+ // no coordinator, so presumed abort unless we have better information.
+ if (_committed)
+ s = org.omg.CosTransactions.Status.StatusCommitted;
+ else
s = org.omg.CosTransactions.Status.StatusRolledBack;
}
catch (NotPrepared ex1)
Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/SubordinateAtomicTransaction.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/SubordinateAtomicTransaction.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/SubordinateAtomicTransaction.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -31,6 +31,7 @@
import javax.transaction.Status;
import org.omg.CORBA.SystemException;
+import org.omg.CORBA.UNKNOWN;
import org.omg.CosTransactions.HeuristicHazard;
import org.omg.CosTransactions.HeuristicMixed;
import org.omg.CosTransactions.NoTransaction;
@@ -175,6 +176,10 @@
{
return ActionStatus.ABORTED;
}
+ catch (final UNKNOWN ex)
+ {
+ return ActionStatus.COMMITTING; // recovery to kick in.
+ }
catch (final Exception ex)
{
return ActionStatus.H_HAZARD;
Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/TransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/TransactionImple.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/TransactionImple.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -332,6 +332,7 @@
{
case ActionStatus.COMMITTED:
case ActionStatus.H_COMMIT:
+ case ActionStatus.COMMITTING:
break;
case ActionStatus.ABORTED:
case ActionStatus.ABORTING:
Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/ExtendedResourceRecord.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/ExtendedResourceRecord.java 2009-08-27 16:32:09 UTC (rev 29094)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/ExtendedResourceRecord.java 2009-08-27 21:36:39 UTC (rev 29095)
@@ -640,12 +640,25 @@
}
catch (TRANSACTION_ROLLEDBACK e4)
{
- return TwoPhaseOutcome.FINISH_ERROR;
+ /*
+ * It rolled back. That's ok, but we need to be able
+ * to communicate that back to the caller.
+ */
+
+ return TwoPhaseOutcome.HEURISTIC_ROLLBACK; // TODO TPO extension required.
}
catch (INVALID_TRANSACTION e5)
{
return TwoPhaseOutcome.FINISH_ERROR;
}
+ catch (final UNKNOWN ex)
+ {
+ /*
+ * Means we can retry.
+ */
+
+ return TwoPhaseOutcome.FINISH_ERROR;
+ }
catch (Exception e5)
{
e5.printStackTrace();
More information about the jboss-svn-commits
mailing list