[jboss-svn-commits] JBL Code SVN: r31932 - 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 Mar 4 08:03:01 EST 2010
Author: jhalliday
Date: 2010-03-04 08:03:00 -0500 (Thu, 04 Mar 2010)
New Revision: 31932
Added:
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/JTANodeNameXAResourceOrphanFilter.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/JTATransactionLogXAResourceOrphanFilter.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/NodeNameXAResourceOrphanFilter.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/recovery/XAResourceOrphanFilter.java
labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/recovery/XAResourceOrphanFilterTest.java
Modified:
labs/jbosstm/trunk/ArjunaJTA/jbossts-properties-arjunajta.xml
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/RecoveryXids.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/jta/common/JTAEnvironmentBean.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBeanMBean.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/xa/XATxConverter.java
labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/recovery/XARecoveryModuleUnitTest.java
labs/jbosstm/trunk/ArjunaJTS/jbossts-properties-arjunajts.xml
labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml
labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts
Log:
Allow configurable handling of in-doubt xids during recovery. JBTM-723
Modified: labs/jbosstm/trunk/ArjunaJTA/jbossts-properties-arjunajta.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jbossts-properties-arjunajta.xml 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/ArjunaJTA/jbossts-properties-arjunajta.xml 2010-03-04 13:03:00 UTC (rev 31932)
@@ -66,7 +66,12 @@
<!-- Which Xid types to recover -->
<entry key="JTAEnvironmentBean.xaRecoveryNodes">1</entry>
-
+
+ <entry key="JTAEnvironmentBean.xaResourceOrphanFilters">
+ com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter
+ com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter
+ </entry>
+
<!--
Base port number for determining a unique number to associate with an instance of the transaction service
(which is needed in order to support multiple instances on the same machine).
Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/JTANodeNameXAResourceOrphanFilter.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/JTANodeNameXAResourceOrphanFilter.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/JTANodeNameXAResourceOrphanFilter.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and/or its affiliates,
+ * and individual contributors as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss, by Red Hat.
+ */
+package com.arjuna.ats.internal.jta.recovery.arjunacore;
+
+import com.arjuna.ats.jta.recovery.XAResourceOrphanFilter;
+import com.arjuna.ats.jta.xa.XATxConverter;
+
+import javax.transaction.xa.Xid;
+
+/**
+ * An XAResourceOrphanFilter for JTA top level transactions, which uses node name information
+ * encoded in the xid to determine if they should be rolled back or not.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com), 2010-03
+ */
+public class JTANodeNameXAResourceOrphanFilter implements XAResourceOrphanFilter
+{
+ private final XAResourceOrphanFilter nodeNameFilter = new NodeNameXAResourceOrphanFilter();
+
+ protected final int myFormatId = XATxConverter.FORMAT_ID;
+
+ @Override
+ public Vote checkXid(Xid xid)
+ {
+ if(xid.getFormatId() != myFormatId) {
+ return Vote.ABSTAIN;
+ }
+
+ return nodeNameFilter.checkXid(xid);
+ }
+}
\ No newline at end of file
Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/JTATransactionLogXAResourceOrphanFilter.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/JTATransactionLogXAResourceOrphanFilter.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/JTATransactionLogXAResourceOrphanFilter.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -0,0 +1,144 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and/or its affiliates,
+ * and individual contributors as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss, by Red Hat.
+ */
+package com.arjuna.ats.internal.jta.recovery.arjunacore;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.TxControl;
+import com.arjuna.ats.arjuna.logging.FacilityCode;
+import com.arjuna.ats.arjuna.objectstore.ObjectStore;
+import com.arjuna.ats.arjuna.objectstore.StateStatus;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.AtomicAction;
+import com.arjuna.ats.jta.logging.jtaLogger;
+import com.arjuna.ats.jta.recovery.XAResourceOrphanFilter;
+import com.arjuna.ats.jta.xa.XATxConverter;
+import com.arjuna.ats.jta.xa.XidImple;
+import com.arjuna.common.util.logging.DebugLevel;
+import com.arjuna.common.util.logging.VisibilityLevel;
+
+import javax.transaction.xa.Xid;
+
+/**
+ * An XAResourceOrphanFilter which vetos rollback for xids owned by top level JTA transactions.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com), 2010-03
+ */
+public class JTATransactionLogXAResourceOrphanFilter implements XAResourceOrphanFilter
+{
+ @Override
+ public Vote checkXid(Xid xid)
+ {
+ if(xid.getFormatId() != XATxConverter.FORMAT_ID) {
+ // we only care about Xids created by the JTA
+ return Vote.ABSTAIN;
+ }
+
+ if(transactionLog(xid)) {
+ // it's owned by a logged transaction which
+ // will recover it top down in due course
+ return Vote.LEAVE_ALONE;
+ }
+
+ return Vote.ABSTAIN;
+ }
+
+ /**
+ * Is there a log file for this transaction?
+ *
+ * @param xid the transaction to check.
+ *
+ * @return <code>boolean</code>true if there is a log file,
+ * <code>false</code> if there isn't.
+ *
+ * @message com.arjuna.ats.internal.jta.recovery.notaxid {0} not an Arjuna
+ * XID
+ */
+ private boolean transactionLog(Xid xid)
+ {
+ ObjectStore transactionStore = TxControl.getStore();
+ String transactionType = new AtomicAction().type();
+
+ XidImple theXid = new XidImple(xid);
+ Uid u = theXid.getTransactionUid();
+
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PRIVATE,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "Checking whether Xid "
+ + theXid + " exists in ObjectStore.");
+ }
+
+ if (!u.equals(Uid.nullUid()))
+ {
+ try
+ {
+
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PRIVATE,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "Looking for "+u+" and "+transactionType);
+ }
+
+ if (transactionStore.currentState(u, transactionType) != StateStatus.OS_UNKNOWN)
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PRIVATE,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "Found record for "+theXid);
+ }
+
+ return true;
+ }
+ else
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PRIVATE,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "No record found for "+theXid);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ else
+ {
+ if (jtaLogger.logger.isInfoEnabled())
+ {
+ jtaLogger.loggerI18N.info(
+ "com.arjuna.ats.internal.jta.recovery.notaxid",
+ new Object[]
+ { xid });
+ }
+ }
+
+ return false;
+ }
+}
Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/NodeNameXAResourceOrphanFilter.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/NodeNameXAResourceOrphanFilter.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/NodeNameXAResourceOrphanFilter.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and/or its affiliates,
+ * and individual contributors as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss, by Red Hat.
+ */
+package com.arjuna.ats.internal.jta.recovery.arjunacore;
+
+import com.arjuna.ats.arjuna.logging.FacilityCode;
+import com.arjuna.ats.internal.jta.utils.XAUtils;
+import com.arjuna.ats.jta.common.jtaPropertyManager;
+import com.arjuna.ats.jta.logging.jtaLogger;
+import com.arjuna.ats.jta.recovery.XAResourceOrphanFilter;
+import com.arjuna.common.util.logging.DebugLevel;
+import com.arjuna.common.util.logging.VisibilityLevel;
+
+import javax.transaction.xa.Xid;
+import java.util.List;
+
+/**
+ * An XAResourceOrphanFilter which uses node name information encoded in the xid to determine if
+ * they should be rolled back or not.
+ *
+ * Note that this filter does not check xid format id, and therefore may attempt to extract node name
+ * information from foreign xids, resulting in random behaviour. Probably best combined with a filter
+ * that verifies formatIds.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com), 2010-03
+ */
+public class NodeNameXAResourceOrphanFilter implements XAResourceOrphanFilter
+{
+ private static final String RECOVER_ALL_NODES = "*";
+
+ @Override
+ public Vote checkXid(Xid xid)
+ {
+ List<String> _xaRecoveryNodes = jtaPropertyManager.getJTAEnvironmentBean().getXaRecoveryNodes();
+
+ if(_xaRecoveryNodes == null || _xaRecoveryNodes.size() == 0) {
+ doWarning();
+ return Vote.ABSTAIN;
+ }
+
+ if ((_xaRecoveryNodes.contains(RECOVER_ALL_NODES)))
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(
+ DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PRIVATE,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "Ignoring node name. Will recover "+ xid);
+ }
+
+ return Vote.ROLLBACK;
+ }
+
+ String nodeName = XAUtils.getXANodeName(xid);
+
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PRIVATE,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "node name of " + xid +" is "+nodeName);
+ }
+
+ if (_xaRecoveryNodes.contains(nodeName))
+ {
+ return Vote.ROLLBACK;
+ }
+ else
+ {
+ return Vote.ABSTAIN;
+ }
+ }
+
+ /**
+ * @message com.arjuna.ats.internal.jta.recovery.noxanodes No XA recovery
+ * nodes specified. May not recover orphans.
+ */
+ private void doWarning() {
+ if (jtaLogger.loggerI18N.isInfoEnabled())
+ {
+ jtaLogger.loggerI18N
+ .info("com.arjuna.ats.internal.jta.recovery.noxanodes");
+ }
+ }
+}
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/RecoveryXids.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/RecoveryXids.java 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/RecoveryXids.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -110,7 +110,7 @@
* they won't appear in the next new list of inflight transactions.
*/
- public final java.lang.Object[] toRecover ()
+ public final Xid[] toRecover ()
{
final int numScanN = (_scanN == null ? 0 : _scanN.length) ;
final int numScanM = (_scanM == null ? 0 : _scanM.length) ;
@@ -121,7 +121,7 @@
return null ;
}
- final Vector workingVector = new Vector() ;
+ final Vector<Xid> workingVector = new Vector<Xid>() ;
for (int count = 0 ; count < numScan ; count++)
{
@@ -131,7 +131,7 @@
}
}
- return workingVector.toArray();
+ return workingVector.toArray(new Xid[workingVector.size()]);
}
public final boolean isSameRM (XAResource xares)
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 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/XARecoveryModule.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -40,14 +40,12 @@
import com.arjuna.ats.arjuna.logging.FacilityCode;
import com.arjuna.ats.internal.arjuna.common.UidHelper;
-import com.arjuna.ats.internal.jta.utils.XAUtils;
import com.arjuna.ats.internal.jta.transaction.arjunacore.AtomicAction;
import com.arjuna.ats.jta.logging.jtaLogger;
import com.arjuna.ats.jta.common.jtaPropertyManager;
import com.arjuna.ats.jta.recovery.*;
import com.arjuna.ats.jta.utils.XAHelper;
-import com.arjuna.ats.jta.xa.XidImple;
import com.arjuna.common.util.logging.*;
@@ -65,13 +63,7 @@
public class XARecoveryModule implements RecoveryModule
{
- // why not in Environment?
-
- public static final String XARecoveryPropertyNamePrefix = "com.arjuna.ats.jta.recovery.XAResourceRecovery";
-
- private static final String RECOVER_ALL_NODES = "*";
-
- public XARecoveryModule()
+ public XARecoveryModule()
{
this(
com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryResourceManagerImple.class
@@ -95,7 +87,22 @@
}
}
+ public void addXAResourceOrphanFilter(XAResourceOrphanFilter xaResourceOrphanFilter) {
+ synchronized (_xaResourceOrphanFilters) {
+ if(!_xaResourceOrphanFilters.contains(xaResourceOrphanFilter)) {
+ _xaResourceOrphanFilters.add(xaResourceOrphanFilter);
+ }
+ }
+ }
+
+ public void removeXAResourceOrphanFilter(XAResourceOrphanFilter xaResourceOrphanFilter) {
+ synchronized (_xaResourceOrphanFilters) {
+ _xaResourceOrphanFilters.remove(xaResourceOrphanFilter);
+ }
+ }
+
+
/**
* @message com.arjuna.ats.internal.jta.recovery.xafirstpass {0} - first
* pass
@@ -232,8 +239,7 @@
}
/**
- * @param Xid
- * xid The transaction to commit/rollback.
+ * @param xid The transaction to commit/rollback.
*
* @return the XAResource than can be used to commit/rollback the specified
* transaction.
@@ -368,19 +374,26 @@
}
}
}
- }
- // Find the node(s) we can recover on behalf of.
- _xaRecoveryNodes = new Vector<String>(jtaPropertyManager.getJTAEnvironmentBean().getXaRecoveryNodes());
-
- if ((_xaRecoveryNodes == null) || (_xaRecoveryNodes.size() == 0))
- {
- if (jtaLogger.loggerI18N.isInfoEnabled())
- {
- jtaLogger.loggerI18N
- .info("com.arjuna.ats.internal.jta.recovery.noxanodes");
- }
- }
+ for(String xaResourceOrphanFilterClassname : jtaPropertyManager.getJTAEnvironmentBean().getXaResourceOrphanFilters())
+ {
+ try
+ {
+ Class c = Thread.currentThread().getContextClassLoader().loadClass(xaResourceOrphanFilterClassname);
+ XAResourceOrphanFilter filter = (XAResourceOrphanFilter)c.newInstance();
+ _xaResourceOrphanFilters.add(filter);
+ }
+ catch(Exception e)
+ {
+ if (jtaLogger.loggerI18N.isWarnEnabled())
+ {
+ jtaLogger.loggerI18N
+ .warn("com.arjuna.ats.internal.jta.recovery.general",
+ new Object[] { e, xaResourceOrphanFilterClassname }, e);
+ }
+ }
+ }
+ }
}
/**
@@ -395,8 +408,6 @@
* resource to table: no XID value available.
* @message com.arjuna.ats.internal.jta.recovery.unexpectedrecoveryerror
* Unexpceted recovery error:
- * @message com.arjuna.ats.internal.jta.recovery.noxanodes No XA recovery
- * nodes specified. Will only recover saved states.
*/
private final boolean transactionInitiatedRecovery()
@@ -806,7 +817,7 @@
xidsToRecover.nextScan(trans);
- Object[] xids = xidsToRecover.toRecover();
+ Xid[] xids = xidsToRecover.toRecover();
if (xids != null)
{
@@ -834,7 +845,7 @@
{
// is the xid known to be one that couldn't be recovered
- recordUid = previousFailure((Xid) xids[j]);
+ recordUid = previousFailure(xids[j]);
if ((recordUid == null) && (foundTransaction))
break; // end
@@ -845,215 +856,16 @@
// transaction
if (recordUid == null)
+ {
+ /*
+ * It wasn't an xid that we couldn't recover, so the
+ * RM knows about it, but we don't. Therefore it may
+ * have to be rolled back.
+ */
+ doForget = handleOrphan(xares, xids[j]);
+ }
+ else
{
- /*
- * It wasn't an xid that we couldn't recover, so the
- * RM knows about it, but we don't. Therefore it may
- * have to be rolled back.
- */
-
- if (jtaLogger.logger.isDebugEnabled())
- {
- jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Checking node name of "
- + ((Xid) xids[j]));
- }
-
- String nodeName = XAUtils
- .getXANodeName((Xid) xids[j]);
- boolean doRecovery = false;
-
- if (jtaLogger.logger.isDebugEnabled())
- {
- jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Node name is " + nodeName);
- }
-
- /*
- * If there is no node name but we have been told to
- * recover everything, then we can roll it back.
- */
-
- if ((nodeName == null)
- && (_xaRecoveryNodes != null)
- && (_xaRecoveryNodes
- .contains(RECOVER_ALL_NODES)))
- {
- if (jtaLogger.logger.isDebugEnabled())
- {
- jtaLogger.logger.debug(
- DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Ignoring node name. Will recover "+(Xid) xids[j]);
- }
-
- doRecovery = true;
- }
- else
- {
- if (nodeName != null)
- {
- /*
- * Check that the node name is in our
- * recovery set or that we have been told to
- * recover everything.
- */
-
- if (_xaRecoveryNodes != null)
- {
- if (_xaRecoveryNodes
- .contains(RECOVER_ALL_NODES)
- || _xaRecoveryNodes
- .contains(nodeName))
- {
- if (jtaLogger.loggerI18N
- .isDebugEnabled())
- {
- jtaLogger.logger
- .debug(
- DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Node name matches. Will recover "+(Xid) xids[j]);
- }
-
- doRecovery = true;
- }
- else
- {
- if (jtaLogger.loggerI18N
- .isDebugEnabled())
- {
- jtaLogger.logger
- .debug(
- DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Node name does not match. Ignoring Xid.");
- }
- }
- }
- else
- {
- if (jtaLogger.loggerI18N
- .isDebugEnabled())
- {
- jtaLogger.logger
- .debug(
- DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Node name not set. Ignoring Xid.");
- }
- }
- }
- else
- {
- if (jtaLogger.logger.isDebugEnabled())
- {
- jtaLogger.logger
- .debug(
- DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Will not recover this Xid");
- }
- }
- }
-
- try
- {
- if (doRecovery)
- {
- if (!transactionLog((Xid) xids[j]))
- {
- if (jtaLogger.loggerI18N.isInfoEnabled())
- {
- jtaLogger.loggerI18N
- .info(
- "com.arjuna.ats.internal.jta.recovery.info.rollingback",
- new Object[]
- { XAHelper
- .xidToString((Xid) xids[j]) });
- }
-
- xares.rollback((Xid) xids[j]);
- }
- else
- {
- if (jtaLogger.loggerI18N.isInfoEnabled())
- {
- jtaLogger.loggerI18N
- .info(
- "com.arjuna.ats.internal.jta.recovery.info.rollingbackignore",
- new Object[]
- { XAHelper
- .xidToString((Xid) xids[j]) });
- }
-
- /*
- * Ignore it as the transaction system
- * will recovery it eventually.
- */
- }
- }
- else
- {
- if (jtaLogger.loggerI18N.isInfoEnabled())
- {
- jtaLogger.loggerI18N
- .info(
- "com.arjuna.ats.internal.jta.recovery.info.notrollback",
- new Object[]
- { XAHelper
- .xidToString((Xid) xids[j]) });
- }
- }
- }
- catch (XAException e1)
- {
- e1.printStackTrace();
-
- switch (e1.errorCode)
- {
- case XAException.XAER_RMERR:
- break;
- case XAException.XA_HEURHAZ:
- case XAException.XA_HEURCOM:
- case XAException.XA_HEURMIX:
- case XAException.XA_HEURRB:
- case XAException.XA_RBROLLBACK:
- {
- if (!doForget) // already done?
- doForget = true;
- }
- break;
- default:
- break;
- }
- }
- catch (Exception e2)
- {
- if (jtaLogger.loggerI18N.isWarnEnabled())
- {
- jtaLogger.loggerI18N
- .warn(
- "com.arjuna.ats.internal.jta.recovery.xarecovery2",
- new Object[]
- {
- _logName
- + ".xaRecovery ",
- e2 });
- }
- }
- }
- else
- {
foundTransaction = true;
/*
@@ -1089,7 +901,7 @@
{
try
{
- xares.forget((Xid) xids[j]);
+ xares.forget(xids[j]);
}
catch (Exception e)
{
@@ -1142,6 +954,84 @@
}
/**
+ * Apply use configurable filtering to determine how to handle the in-doubt resource.
+ *
+ * @param xares
+ * @param xid
+ * @return true if forget should be called, false otherwise.
+ */
+ private boolean handleOrphan(XAResource xares, Xid xid)
+ {
+ // be default we play it safe and leave resources alone unless a filter explicitly recognizes them.
+ // getting presumed abort behaviour therefore requires appropriate filters to be registered.
+ XAResourceOrphanFilter.Vote votingOutcome = XAResourceOrphanFilter.Vote.LEAVE_ALONE;
+
+ for(XAResourceOrphanFilter filter : _xaResourceOrphanFilters) {
+ XAResourceOrphanFilter.Vote vote = filter.checkXid(xid);
+
+ if(jtaLogger.logger.isDebugEnabled()) {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PRIVATE,
+ FacilityCode.FAC_CRASH_RECOVERY, "XAResourceOrphanFilter "+filter.getClass().getName()+" voted "+vote);
+ }
+
+ if(vote == XAResourceOrphanFilter.Vote.LEAVE_ALONE)
+ {
+ return false;
+ }
+ else if(vote == XAResourceOrphanFilter.Vote.ROLLBACK)
+ {
+ votingOutcome = vote;
+ }
+ }
+
+ try
+ {
+ if(votingOutcome == XAResourceOrphanFilter.Vote.ROLLBACK)
+ {
+ if (jtaLogger.loggerI18N.isInfoEnabled())
+ {
+ jtaLogger.loggerI18N
+ .info("com.arjuna.ats.internal.jta.recovery.info.rollingback",
+ new Object[] { XAHelper.xidToString(xid) });
+ }
+
+ xares.rollback(xid);
+ }
+ }
+ catch (XAException e1)
+ {
+ e1.printStackTrace();
+
+ switch (e1.errorCode)
+ {
+ case XAException.XAER_RMERR:
+ break;
+ case XAException.XA_HEURHAZ:
+ case XAException.XA_HEURCOM:
+ case XAException.XA_HEURMIX:
+ case XAException.XA_HEURRB:
+ case XAException.XA_RBROLLBACK:
+ {
+ return true;
+ }
+ default:
+ break;
+ }
+ }
+ catch (Exception e2)
+ {
+ if (jtaLogger.loggerI18N.isWarnEnabled())
+ {
+ jtaLogger.loggerI18N
+ .warn(
+ "com.arjuna.ats.internal.jta.recovery.xarecovery2",
+ new Object[] { _logName + ".xaRecovery ", e2 });
+ }
+ }
+ return false;
+ }
+
+ /**
* For some drivers, isSameRM is connection specific. If we have prev scan results
* for the same RM but using a different connection, we need to be able to identify them.
* Look at the data from previous scans, identify any for the same RM but different XAResource
@@ -1175,93 +1065,6 @@
}
/**
- * Is there a log file for this transaction?
- *
- * @param Xid
- * xid the transaction to check.
- *
- * @return <code>boolean</code>true if there is a log file,
- * <code>false</code> if there isn't.
- *
- * @message com.arjuna.ats.internal.jta.recovery.notaxid {0} not an Arjuna
- * XID
- */
-
- private final boolean transactionLog(Xid xid)
- {
- if (_transactionStore == null)
- {
- _transactionStore = TxControl.getStore();
- }
-
- XidImple theXid = new XidImple(xid);
- Uid u = theXid.getTransactionUid();
-
- if (jtaLogger.logger.isDebugEnabled())
- {
- jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Checking whether Xid "
- + theXid + " exists in ObjectStore.");
- }
-
- if (!u.equals(Uid.nullUid()))
- {
- try
- {
-
- if (jtaLogger.logger.isDebugEnabled())
- {
- jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Looking for "+u+" and "+_transactionType);
- }
-
- if (_transactionStore.currentState(u, _transactionType) != StateStatus.OS_UNKNOWN)
- {
- if (jtaLogger.logger.isDebugEnabled())
- {
- jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "Found record for "+theXid);
- }
-
- return true;
- }
- else
- {
- if (jtaLogger.logger.isDebugEnabled())
- {
- jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PRIVATE,
- FacilityCode.FAC_CRASH_RECOVERY,
- "No record found for "+theXid);
- }
- }
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- else
- {
- if (jtaLogger.logger.isInfoEnabled())
- {
- jtaLogger.loggerI18N.info(
- "com.arjuna.ats.internal.jta.recovery.notaxid",
- new Object[]
- { xid });
- }
- }
-
- return false;
- }
-
- /**
* Is the Xid is in the failure list, i.e., the list of those transactions
* we couldn't recover, possibly because of transient failures. If so,
* return the uid of (one of) the records and remove it from the list.
@@ -1369,6 +1172,8 @@
private final List<XAResourceRecoveryHelper> _xaResourceRecoveryHelpers = new LinkedList<XAResourceRecoveryHelper>();
+ private final List<XAResourceOrphanFilter> _xaResourceOrphanFilters = new LinkedList<XAResourceOrphanFilter>();
+
private Hashtable _failures = null;
private Vector _xaRecoveryNodes = null;
@@ -1385,8 +1190,6 @@
// Reference to the Object Store.
private static ObjectStore _transactionStore = null;
- // milliseconds
-
private static final char BREAKCHARACTER = ';'; // delimiter for xaconnrecov
// property
}
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBean.java 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBean.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -47,6 +47,8 @@
@ConcatenationPrefix(prefix = "com.arjuna.ats.jta.recovery.XAResourceRecovery")
private volatile List<String> xaResourceRecoveryInstances = new ArrayList<String>();
+ private volatile List<String> xaResourceOrphanFilters = new ArrayList<String>();
+
private volatile boolean xaRollbackOptimization = false;
private volatile boolean xaAssumeRecoveryComplete = false;
@@ -218,6 +220,36 @@
}
/**
+ * Returns a list of names of classes that implement XAResourceOrphanFilter.
+ * The returned list is a copy. May return an empty list, will not return null.
+ *
+ * Default: empty list.
+ * Equivalent deprecated property prefix:
+ *
+ * @return a list of XAResourceOrphanFilter implementation class names.
+ */
+ public List<String> getXaResourceOrphanFilters()
+ {
+ return new ArrayList<String>(xaResourceOrphanFilters);
+ }
+
+ /**
+ * Sets the XAResource orphan filters.
+ * List elements should be names of classes that implement XAResourceOrphanFilter.
+ * The provided list will be copied, not retained.
+ *
+ * @param xaResourceOrphanFilters a list of XAResourceOrphanFilter implementation classes.
+ */
+ public void setXaResourceOrphanFilters(List<String> xaResourceOrphanFilters)
+ {
+ if(xaResourceOrphanFilters == null) {
+ this.xaResourceOrphanFilters = new ArrayList<String>();
+ } else {
+ this.xaResourceOrphanFilters = new ArrayList<String>(xaResourceOrphanFilters);
+ }
+ }
+
+ /**
* Returns if connections associated to XAResources that fail during prepare should be cleaned up immediately.
* TODO move to JDBC module as it's only for our own connection manager?
*
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBeanMBean.java 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBeanMBean.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -52,7 +52,11 @@
List<String> getXaResourceRecoveryInstances();
void setXaResourceRecoveryInstances(List<String> xaResourceRecoveryInstances);
-
+
+ List<String> getXaResourceOrphanFilters();
+
+ void setXaResourceOrphanFilters(List<String> xaResourceOrphanFilters);
+
boolean isXaRollbackOptimization();
void setXaRollbackOptimization(boolean xaRollbackOptimization);
Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/recovery/XAResourceOrphanFilter.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/recovery/XAResourceOrphanFilter.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/recovery/XAResourceOrphanFilter.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and/or its affiliates,
+ * and individual contributors as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss, by Red Hat.
+ */
+package com.arjuna.ats.jta.recovery;
+
+import javax.transaction.xa.Xid;
+
+/**
+ * Interface used by the XARecoveryModule to allow plugins to vote in the handling of in-doubt Xids.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com), 2010-03
+ */
+public interface XAResourceOrphanFilter
+{
+ public enum Vote { ABSTAIN, ROLLBACK, LEAVE_ALONE }
+
+ /**
+ * Called by the XARecoveryModule for each in-doubt Xid.
+ * Implementations should return
+ * Vote.ROLLBACK if they recognize the xid and believe it should be aborted.
+ * Vote.LEAVE_ALONE if they recognize the xid and do not want the XARecovery module to roll it back.
+ * Vote.ABSTAIN if they do not recognize the xid.
+ * Each registered XAResourceOrphanFilter will be consulted before any rollback on each recovery pass,
+ * so they may change their mind over time e.g. if new information becomes available due to other recovery
+ * activity.
+ *
+ * @param xid The in-doubt xid.
+ * @return a Vote in accordance with the guidelines above.
+ */
+ public Vote checkXid(Xid xid);
+}
\ No newline at end of file
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/xa/XATxConverter.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/xa/XATxConverter.java 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/xa/XATxConverter.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -153,10 +153,8 @@
public static String getNodeName(XID xid)
{
- if(xid.formatID != FORMAT_ID) {
- return null;
- }
-
+ // don't check the formatId - it may differ e.g. JTA vs. JTS.
+
// the node name follows the Uid with no separator, so the only
// way to tell where it starts is to figure out how long the Uid is.
Uid uid = getUid(xid);
Modified: labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/recovery/XARecoveryModuleUnitTest.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/recovery/XARecoveryModuleUnitTest.java 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/recovery/XARecoveryModuleUnitTest.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -33,6 +33,8 @@
import java.util.ArrayList;
+import com.arjuna.ats.jta.recovery.XAResourceOrphanFilter;
+import com.arjuna.ats.jta.recovery.XAResourceRecoveryHelper;
import org.junit.Test;
import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
@@ -41,6 +43,9 @@
import com.arjuna.ats.jta.common.jtaPropertyManager;
import com.hp.mwtests.ts.jta.common.RecoveryXAResource;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
import static org.junit.Assert.*;
public class XARecoveryModuleUnitTest
@@ -76,4 +81,48 @@
xarm.periodicWorkSecondPass();
}
}
+
+ @Test
+ public void testXAResourceRecoveryHelperRegistration() {
+
+ XARecoveryModule xaRecoveryModule = new XARecoveryModule();
+ XAResourceRecoveryHelper xaResourceRecoveryHelper = new DummyXAResourceRecoveryHelper();
+
+ xaRecoveryModule.addXAResourceRecoveryHelper(xaResourceRecoveryHelper);
+ xaRecoveryModule.removeXAResourceRecoveryHelper(xaResourceRecoveryHelper);
+ }
+
+ class DummyXAResourceRecoveryHelper implements XAResourceRecoveryHelper {
+ @Override
+ public boolean initialise(String p) throws Exception
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ public XAResource[] getXAResources() throws Exception
+ {
+ return new XAResource[0]; //To change body of implemented methods use File | Settings | File Templates.
+ }
+ }
+
+ @Test
+ public void testXAResourceOrphanFilterRegistration() {
+
+ XARecoveryModule xaRecoveryModule = new XARecoveryModule();
+ XAResourceOrphanFilter xaResourceOrphanFilter = new DummyXAResourceOrphanFilter();
+
+ xaRecoveryModule.addXAResourceOrphanFilter(xaResourceOrphanFilter);
+ xaRecoveryModule.removeXAResourceOrphanFilter(xaResourceOrphanFilter);
+
+ }
+
+ class DummyXAResourceOrphanFilter implements XAResourceOrphanFilter
+ {
+ @Override
+ public Vote checkXid(Xid xid)
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+ }
}
Added: labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/recovery/XAResourceOrphanFilterTest.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/recovery/XAResourceOrphanFilterTest.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/recovery/XAResourceOrphanFilterTest.java 2010-03-04 13:03:00 UTC (rev 31932)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and/or its affiliates,
+ * and individual contributors as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss, by Red Hat.
+ */
+package com.hp.mwtests.ts.jta.recovery;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.TxControl;
+import com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter;
+import com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter;
+import com.arjuna.ats.jta.common.jtaPropertyManager;
+import com.arjuna.ats.jta.recovery.XAResourceOrphanFilter;
+import com.arjuna.ats.jta.xa.XATxConverter;
+
+import javax.transaction.xa.Xid;
+
+import org.junit.Test;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+/**
+ * Unit tests for JTA package XAResourceOrphanFilter implementations.
+ *
+ * @author Jonathan Halliday (jonathan.halliday at redhat.com), 2010-03
+ */
+public class XAResourceOrphanFilterTest
+{
+ @Test
+ public void testJTANodeNameXAResourceOrphanFilter()
+ {
+ XAResourceOrphanFilter orphanFilter = new JTANodeNameXAResourceOrphanFilter();
+
+ Xid notJTAFormatId = XATxConverter.getXid(new Uid(), false, 0);
+ assertEquals(XAResourceOrphanFilter.Vote.ABSTAIN, orphanFilter.checkXid(notJTAFormatId));
+
+ List<String> recoveryNodes = new LinkedList<String>();
+ recoveryNodes.add("AA");
+ jtaPropertyManager.getJTAEnvironmentBean().setXaRecoveryNodes(recoveryNodes);
+
+ byte[] notRecoverableNodeName = new byte[] { 'A', 'B' };
+ TxControl.setXANodeName(notRecoverableNodeName);
+ Xid jtaNotRecoverableNodeName = XATxConverter.getXid(new Uid(), false, XATxConverter.FORMAT_ID);
+
+ assertEquals(XAResourceOrphanFilter.Vote.ABSTAIN, orphanFilter.checkXid(jtaNotRecoverableNodeName));
+
+ byte[] recoverableNodeName = new byte[] { 'A', 'A' };
+ TxControl.setXANodeName(recoverableNodeName);
+ Xid jtaRecoverableNodeName = XATxConverter.getXid(new Uid(), false, XATxConverter.FORMAT_ID);
+
+ assertEquals(XAResourceOrphanFilter.Vote.ROLLBACK, orphanFilter.checkXid(jtaRecoverableNodeName));
+
+ recoveryNodes.clear();
+ recoveryNodes.add("*");
+ jtaPropertyManager.getJTAEnvironmentBean().setXaRecoveryNodes(recoveryNodes);
+
+ assertEquals(XAResourceOrphanFilter.Vote.ROLLBACK, orphanFilter.checkXid(jtaNotRecoverableNodeName));
+ assertEquals(XAResourceOrphanFilter.Vote.ROLLBACK, orphanFilter.checkXid(jtaRecoverableNodeName));
+ }
+
+ @Test
+ public void testJTATransactionLogOrphanFilter()
+ {
+ XAResourceOrphanFilter orphanFilter = new JTATransactionLogXAResourceOrphanFilter();
+
+ Xid notJTAFormatId = XATxConverter.getXid(new Uid(), false, 0);
+ assertEquals(XAResourceOrphanFilter.Vote.ABSTAIN, orphanFilter.checkXid(notJTAFormatId));
+
+ Xid jtaFormatId = XATxConverter.getXid(new Uid(), false, XATxConverter.FORMAT_ID);
+ assertEquals(XAResourceOrphanFilter.Vote.ABSTAIN, orphanFilter.checkXid(jtaFormatId));
+ }
+}
Modified: labs/jbosstm/trunk/ArjunaJTS/jbossts-properties-arjunajts.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jbossts-properties-arjunajts.xml 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/ArjunaJTS/jbossts-properties-arjunajts.xml 2010-03-04 13:03:00 UTC (rev 31932)
@@ -67,6 +67,11 @@
<!-- Which Xid types to recover -->
<entry key="JTAEnvironmentBean.xaRecoveryNodes">1</entry>
+ <entry key="JTAEnvironmentBean.xaResourceOrphanFilters">
+ com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter
+ com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter
+ </entry>
+
<!--
Base port number for determining a unique number to associate with an instance of the transaction service
(which is needed in order to support multiple instances on the same machine).
Modified: labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml
===================================================================
--- labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml 2010-03-04 13:03:00 UTC (rev 31932)
@@ -141,6 +141,13 @@
<value>1</value>
</list>
</property>
+
+ <property name="xaResourceOrphanFilters" preinstantiate="false">
+ <list elementClass="java.lang.String">
+ <value>com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter</value>
+ <value>com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter</value>
+ </list>
+ </property>
</bean>
Modified: labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts
===================================================================
--- labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts 2010-03-04 12:05:31 UTC (rev 31931)
+++ labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts 2010-03-04 13:03:00 UTC (rev 31932)
@@ -147,6 +147,13 @@
</list>
</property>
+ <property name="xaResourceOrphanFilters" preinstantiate="false">
+ <list elementClass="java.lang.String">
+ <value>com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter</value>
+ <value>com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter</value>
+ </list>
+ </property>
+
</bean>
<bean name="RecoveryManager" class="com.arjuna.ats.jbossatx.jts.RecoveryManagerService">
More information about the jboss-svn-commits
mailing list