[jboss-svn-commits] JBL Code SVN: r17617 - in labs/jbosstm/trunk/ArjunaJTS: jtax/classes/com/arjuna/ats/internal/jta/transaction/jts and 4 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Jan 8 06:28:07 EST 2008
Author: jhalliday
Date: 2008-01-08 06:28:07 -0500 (Tue, 08 Jan 2008)
New Revision: 17617
Added:
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/JTAInterposedSynchronizationImple.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionSynchronizationRegistryImple.java
Modified:
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/SynchronizationImple.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java
labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java
labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/SynchronizationRecord.java
labs/jbosstm/trunk/ArjunaJTS/jts/idl/arjuna/ArjunaOTS.idl
Log:
Added JTA 1.1 support to the JTS (jtax), mainly consisting of copying the TransactionSynchronizationRegistry and associated changes over from the local JTA.See http://jira.jboss.com/jira/browse/JBTM-174
Added: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/JTAInterposedSynchronizationImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/JTAInterposedSynchronizationImple.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/JTAInterposedSynchronizationImple.java 2008-01-08 11:28:07 UTC (rev 17617)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, 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 General Public License, v. 2.0.
+ * 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 General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2007,
+ * @author Red Hat Middleware LLC.
+ */
+package com.arjuna.ats.internal.jta.resources.jts.orbspecific;
+
+import com.arjuna.ArjunaOTS.JTAInterposedSynchronizationOperations;
+
+/**
+ * Implementation of the marker interface used to distinguish Synchronizations that
+ * should be interposed in the JTA 1.1 TransactionSynchronizationRegistry sense of the term.
+ */
+public class JTAInterposedSynchronizationImple extends SynchronizationImple implements JTAInterposedSynchronizationOperations {
+
+ public JTAInterposedSynchronizationImple(javax.transaction.Synchronization ptr) {
+ super(ptr);
+ }
+
+ protected org.omg.PortableServer.Servant getPOATie() {
+ return new com.arjuna.ArjunaOTS.JTAInterposedSynchronizationPOATie(this);
+ }
+}
Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/SynchronizationImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/SynchronizationImple.java 2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/SynchronizationImple.java 2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a full listing
+ * 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 General Public License, v. 2.0.
- * 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
+ * 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 General Public License for more details.
* You should have received a copy of the GNU General Public License,
* v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
- *
+ *
* (C) 2005-2006,
* @author JBoss Inc.
*/
@@ -47,6 +47,7 @@
import com.arjuna.ats.internal.jts.ORBManager;
import com.arjuna.common.util.logging.*;
+import com.arjuna.ArjunaOTS.JTAInterposedSynchronizationHelper;
import org.omg.CosTransactions.*;
@@ -79,9 +80,9 @@
* @since JTS 1.2.4.
*/
-public class SynchronizationImple extends org.omg.CosTransactions.SynchronizationPOA
+public class SynchronizationImple implements org.omg.CosTransactions.SynchronizationOperations
{
-
+
public SynchronizationImple (javax.transaction.Synchronization ptr)
{
_theSynch = ptr;
@@ -103,16 +104,18 @@
public final org.omg.CosTransactions.Synchronization getSynchronization ()
{
- if (_theReference == null)
- {
- ORBManager.getPOA().objectIsReady(this);
-
- _theReference = org.omg.CosTransactions.SynchronizationHelper.narrow(ORBManager.getPOA().corbaReference(this));
- }
-
- return _theReference;
+ if (_theReference == null)
+ {
+ _thePOATie = getPOATie();
+
+ ORBManager.getPOA().objectIsReady(_thePOATie);
+
+ _theReference = org.omg.CosTransactions.SynchronizationHelper.narrow(ORBManager.getPOA().corbaReference(_thePOATie));
+ }
+
+ return _theReference;
}
-
+
public void before_completion () throws org.omg.CORBA.SystemException
{
if (jtaLogger.logger.isDebugEnabled())
@@ -153,14 +156,14 @@
_theSynch.afterCompletion(s);
if (_theReference != null)
- ORBManager.getPOA().shutdownObject(this);
+ ORBManager.getPOA().shutdownObject(_thePOATie);
}
catch (Exception e)
{
e.printStackTrace();
-
+
if (_theReference != null)
- ORBManager.getPOA().shutdownObject(this);
+ ORBManager.getPOA().shutdownObject(_thePOATie);
throw new UNKNOWN(); // should not cause any affect!
}
@@ -169,7 +172,14 @@
throw new UNKNOWN(); // should not cause any affect!
}
+ // this is used to allow subclasses to override the Tie type provided.
+ // the Tie classes do not inherit from one another even if the business interfaces
+ // they correspond to do in the idl. Hence Servant is the only common parent.
+ protected org.omg.PortableServer.Servant getPOATie() {
+ return new org.omg.CosTransactions.SynchronizationPOATie(this);
+ }
+
private javax.transaction.Synchronization _theSynch;
private org.omg.CosTransactions.Synchronization _theReference;
-
+ private org.omg.PortableServer.Servant _thePOATie;
}
Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java 2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java 2008-01-08 11:28:07 UTC (rev 17617)
@@ -66,8 +66,7 @@
import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-import java.util.Hashtable;
-import java.util.Enumeration;
+import java.util.*;
import javax.transaction.RollbackException;
import java.lang.SecurityException;
@@ -445,12 +444,11 @@
* [com.arjuna.ats.internal.jta.transaction.jts.syncerror]
* Synchronizations are not allowed!
*/
-
public void registerSynchronization (javax.transaction.Synchronization sync)
throws javax.transaction.RollbackException,
java.lang.IllegalStateException, javax.transaction.SystemException
{
- if (jtaLogger.logger.isDebugEnabled())
+ if (jtaLogger.logger.isDebugEnabled())
{
jtaLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC, com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA, "TransactionImple.registerSynchronization");
}
@@ -460,13 +458,26 @@
"TransactionImple.registerSynchronization - "
+ jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.nullparam"));
+ registerSynchronizationImple(new SynchronizationImple(sync));
+ }
+
+ // package-private method also for use by
+ // TransactionSynchronizationRegistryImple
+ /**
+ * @message com.arjuna.ats.internal.jta.transaction.arjunacore.syncwhenaborted
+ * [com.arjuna.ats.internal.jta.transaction.arjunacore.syncwhenaborted]
+ * Can't register synchronization because the transaction is in
+ * aborted state
+ */
+ void registerSynchronizationImple(SynchronizationImple synchronizationImple)
+ throws javax.transaction.RollbackException,
+ java.lang.IllegalStateException, javax.transaction.SystemException
+ {
if (_theTransaction != null)
{
try
{
- SynchronizationImple s = new SynchronizationImple(sync);
-
- _theTransaction.registerSynchronization(s.getSynchronization());
+ _theTransaction.registerSynchronization(synchronizationImple.getSynchronization());
}
catch (TRANSACTION_ROLLEDBACK e2)
{
@@ -497,7 +508,8 @@
jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.inactivetx"));
}
- public boolean enlistResource (XAResource xaRes) throws RollbackException,
+
+ public boolean enlistResource (XAResource xaRes) throws RollbackException,
IllegalStateException, javax.transaction.SystemException
{
return enlistResource(xaRes, null);
@@ -1222,15 +1234,41 @@
removeTransaction(this);
}
- protected TransactionImple (AtomicTransaction tx)
+ // get a key-value pair from a transaction specific Map
+ public Object getTxLocalResource(Object key)
{
+ return _txLocalResources.get(key);
+ }
+
+ // store a key-value pair in the scope of the transaction.
+ public void putTxLocalResource(Object key, Object value)
+ {
+ _txLocalResources.put(key, value);
+ }
+
+
+ /*
+ * For JBossAS integration TransactionLocal implementation, we need to know if a tx has been
+ * resolved yet or not. We could use getStatus() and a case stmt, but since an instance is
+ * removed from _transactions on completion this is just as effective.
+ * @param tx
+ * @return
+ */
+ public boolean isAlive() {
+ return _transactions.contains(this);
+ }
+
+
+ protected TransactionImple (AtomicTransaction tx)
+ {
_theTransaction = tx;
if (tx != null)
{
_resources = new Hashtable();
_duplicateResources = new Hashtable();
- }
+ _txLocalResources = Collections.synchronizedMap(new HashMap());
+ }
else
{
_resources = null;
@@ -1282,7 +1320,7 @@
jtaLogger.loggerI18N.warn("com.arjuna.ats.internal.jta.transaction.jts.syncproblem", ex);
}
_xaTransactionTimeoutEnabled = getXATransactionTimeoutEnabled() ;
- }
+ }
protected void commitAndDisassociate ()
throws javax.transaction.RollbackException,
@@ -1761,6 +1799,7 @@
private Hashtable _duplicateResources;
private int _suspendCount;
private final boolean _xaTransactionTimeoutEnabled ;
+ private Map _txLocalResources;
/**
* Count of last resources seen in this transaction.
Added: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionSynchronizationRegistryImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionSynchronizationRegistryImple.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionSynchronizationRegistryImple.java 2008-01-08 11:28:07 UTC (rev 17617)
@@ -0,0 +1,254 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, 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) 2006,
+ * @author JBoss Inc.
+ *
+ * $Id$
+ */
+package com.arjuna.ats.internal.jta.transaction.jts;
+
+import com.arjuna.ats.jta.logging.jtaLogger;
+import com.arjuna.ats.internal.jta.resources.jts.orbspecific.JTAInterposedSynchronizationImple;
+import com.arjuna.common.util.logging.DebugLevel;
+import com.arjuna.common.util.logging.VisibilityLevel;
+
+import javax.transaction.*;
+import java.io.Serializable;
+
+/**
+ * Implementation of the TransactionSynchronizationRegistry interface, in line with the JTA 1.1 specification.
+ *
+ * @author jonathan.halliday at jboss.com
+ */
+public class TransactionSynchronizationRegistryImple implements TransactionSynchronizationRegistry, Serializable {
+
+ // This Imple is stateless and just delegates the work down to the transaction manager.
+ // It's Serilizable so it can be shoved into the app server JNDI.
+
+ /*
+ * http://java.sun.com/javaee/5/docs/api/javax/transaction/TransactionSynchronizationRegistry.html
+ * http://jcp.org/aboutJava/communityprocess/maintenance/jsr907/907ChangeLog.html
+ */
+
+ // Return an opaque object to represent the transaction bound to the current thread at the time this method is called.
+
+ /**
+ * @message com.arjuna.ats.internal.jta.transaction.jts.systemexception
+ * [com.arjuna.ats.internal.jta.transaction.jts.systemexception]
+ * The transaction implementation threw a SystemException
+ */
+ public Object getTransactionKey()
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+ "TransactionSynchronizationRegistryImple.getTransactionKey");
+ }
+
+ javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+ TransactionImple transactionImple = null;
+ try
+ {
+ transactionImple = (TransactionImple)tm.getTransaction();
+ }
+ catch (SystemException e)
+ {
+ throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+ }
+
+ if (transactionImple == null) {
+ return null;
+ } else {
+ return transactionImple.get_uid();
+ }
+ }
+
+ // Add or replace an object in the Map of resources being managed for the transaction bound to the current thread at the time this method is called.
+ public void putResource(Object key, Object value)
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+ "TransactionSynchronizationRegistryImple.putResource");
+ }
+
+ if(key == null)
+ {
+ throw new NullPointerException();
+ }
+
+ TransactionImple transactionImple = getTransactionImple();
+ transactionImple.putTxLocalResource(key, value);
+ }
+
+ // Get an object from the Map of resources being managed for the transaction bound to the current thread at the time this method is called.
+ public Object getResource(Object key)
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+ "TransactionSynchronizationRegistryImple.getResource");
+ }
+
+ if(key == null)
+ {
+ throw new NullPointerException();
+ }
+
+ TransactionImple transactionImple = getTransactionImple();
+ return transactionImple.getTxLocalResource(key);
+ }
+
+ // Register a Synchronization instance with special ordering semantics.
+ /**
+ * @message com.arjuna.ats.internal.jta.transaction.jts.syncrollbackexception
+ * [ccom.arjuna.ats.internal.jta.transaction.jts.syncrollbackexception]
+ * The transaction implementation threw a RollbackException
+ */
+ public void registerInterposedSynchronization(Synchronization synchronization)
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+ "TransactionSynchronizationRegistryImple.registerInterposedSynchronization");
+ }
+
+ TransactionImple transactionImple = getTransactionImple();
+
+ try
+ {
+ transactionImple.registerSynchronizationImple(new JTAInterposedSynchronizationImple(synchronization));
+ }
+ catch (RollbackException e)
+ {
+ throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.syncrollbackmexception"), e);
+ }
+ catch (SystemException e)
+ {
+ throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+ }
+ }
+
+ // Return the status of the transaction bound to the current thread at the time this method is called.
+ public int getTransactionStatus()
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+ "TransactionSynchronizationRegistryImple.getTransactionStatus");
+ }
+
+ javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+ try
+ {
+ return tm.getStatus();
+ }
+ catch(SystemException e)
+ {
+ throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+ }
+
+ }
+
+ // Set the rollbackOnly status of the transaction bound to the current thread at the time this method is called.
+ public void setRollbackOnly()
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+ "TransactionSynchronizationRegistryImple.setRollbackOnly");
+ }
+
+ javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+ try
+ {
+ Transaction transaction = tm.getTransaction();
+
+ if(transaction == null)
+ {
+ throw new IllegalStateException();
+ }
+
+ tm.setRollbackOnly();
+ }
+ catch (SystemException e)
+ {
+ throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+ }
+ }
+
+ // Get the rollbackOnly status of the transaction bound to the current thread at the time this method is called.
+ public boolean getRollbackOnly()
+ {
+ if (jtaLogger.logger.isDebugEnabled())
+ {
+ jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+ "TransactionSynchronizationRegistryImple.getRollbackOnly");
+ }
+
+ TransactionImple transactionImple = getTransactionImple();
+
+ if(transactionImple == null) {
+ throw new IllegalStateException();
+ }
+
+ try
+ {
+ return (transactionImple.getStatus() == Status.STATUS_MARKED_ROLLBACK);
+ }
+ catch (SystemException e)
+ {
+ throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+ }
+ }
+
+ private TransactionImple getTransactionImple() throws IllegalStateException
+ {
+ javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+ TransactionImple transactionImple = null;
+ try
+ {
+ transactionImple = (TransactionImple)tm.getTransaction();
+ }
+ catch (SystemException e)
+ {
+ throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+ }
+
+ if(transactionImple == null)
+ {
+ throw new IllegalStateException();
+ }
+
+ return transactionImple;
+ }
+}
Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java 2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java 2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a full listing
+ * 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 General Public License, v. 2.0.
- * 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
+ * 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 General Public License for more details.
* You should have received a copy of the GNU General Public License,
* v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
- *
+ *
* (C) 2005-2006,
* @author JBoss Inc.
*/
@@ -45,7 +45,6 @@
import com.arjuna.ats.arjuna.coordinator.TxControl;
import com.arjuna.ats.arjuna.objectstore.ObjectStore;
import com.arjuna.ats.arjuna.state.InputObjectState;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TxImporter;
import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple;
import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.coordinator.ServerTransaction;
import com.arjuna.ats.jta.utils.XAHelper;
@@ -53,7 +52,7 @@
/**
* The XATerminator implementation.
- *
+ *
* @author mcl
*
*/
@@ -66,17 +65,17 @@
try
{
TransactionImple tx = TxImporter.getImportedTransaction(xid);
-
+
if (tx == null)
throw new XAException(XAException.XAER_INVAL);
-
+
if (tx.baseXid() != null) // activate failed?
{
if (onePhase)
tx.doOnePhaseCommit();
else
tx.doCommit();
-
+
TxImporter.removeImportedTransaction(xid);
}
else
@@ -85,7 +84,7 @@
catch (XAException ex)
{
// resource hasn't had a chance to recover yet
-
+
if (ex.errorCode != XAException.XA_RETRY)
{
TxImporter.removeImportedTransaction(xid);
@@ -104,20 +103,20 @@
catch (SystemException ex)
{
TxImporter.removeImportedTransaction(xid);
-
+
throw new XAException(XAException.XAER_RMERR);
}
}
-
+
public void forget (Xid xid) throws XAException
{
try
{
TransactionImple tx = TxImporter.getImportedTransaction(xid);
-
+
if (tx == null)
throw new XAException(XAException.XAER_INVAL);
-
+
tx.doForget();
}
catch (Exception ex)
@@ -129,25 +128,25 @@
TxImporter.removeImportedTransaction(xid);
}
}
-
+
public int prepare (Xid xid) throws XAException
{
try
{
TransactionImple tx = TxImporter.getImportedTransaction(xid);
-
+
if (tx == null)
throw new XAException(XAException.XAER_INVAL);
-
+
switch (tx.doPrepare())
{
case TwoPhaseOutcome.PREPARE_READONLY:
TxImporter.removeImportedTransaction(xid);
-
- return XAResource.XA_RDONLY;
+
+ return XAResource.XA_RDONLY;
case TwoPhaseOutcome.PREPARE_NOTOK:
TxImporter.removeImportedTransaction(xid); // TODO check if rollback is going to be called first
-
+
throw new XAException(XAException.XA_RBROLLBACK);
case TwoPhaseOutcome.PREPARE_OK:
return XAResource.XA_OK;
@@ -164,7 +163,7 @@
throw ex;
}
}
-
+
public Xid[] recover (int flag) throws XAException
{
/*
@@ -172,13 +171,13 @@
* transactions. Our own crash recovery takes care of transactions imported
* via CORBA, Web Services etc.
*/
-
+
/*
* Requires going through the objectstore for the states of imported
* transactions. Our own crash recovery takes care of transactions imported
* via CORBA, Web Services etc.
*/
-
+
switch (flag)
{
case XAResource.TMSTARTRSCAN: // check the object store
@@ -199,23 +198,23 @@
default:
throw new XAException(XAException.XAER_PROTO);
}
-
+
// if we are here, then check the object store
-
+
Xid[] indoubt = null;
-
+
try
{
ObjectStore objStore = new ObjectStore(TxControl.getActionStoreType());
InputObjectState states = new InputObjectState();
-
+
// only look in the JCA section of the object store
if (objStore.allObjUids(ServerTransaction.getType(), states) && (states.notempty()))
{
Stack values = new Stack();
boolean finished = false;
-
+
do
{
Uid uid = new Uid(Uid.nullUid());
@@ -239,7 +238,7 @@
}
else
finished = true;
-
+
} while (!finished);
if (values.size() > 0)
@@ -247,7 +246,7 @@
int index = 0;
indoubt = new Xid[values.size()];
-
+
while (!values.empty())
{
TransactionImple id = (TransactionImple) values.pop();
@@ -279,7 +278,7 @@
if (tx.baseXid() != null)
{
tx.doRollback();
-
+
TxImporter.removeImportedTransaction(xid);
}
else
@@ -288,7 +287,7 @@
catch (XAException ex)
{
// resource hasn't had a chance to recover yet
-
+
if (ex.errorCode != XAException.XA_RETRY)
{
TxImporter.removeImportedTransaction(xid);
@@ -307,11 +306,11 @@
catch (SystemException ex)
{
TxImporter.removeImportedTransaction(xid);
-
+
throw new XAException(XAException.XAER_RMERR);
}
}
-
+
private boolean _recoveryStarted = false;
-
+
}
Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java 2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java 2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a full listing
+ * 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 General Public License, v. 2.0.
- * 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
+ * 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 General Public License for more details.
* You should have received a copy of the GNU General Public License,
* v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
- *
+ *
* (C) 2005-2006,
* @author JBoss Inc.
*/
@@ -74,8 +74,9 @@
import com.arjuna.ArjunaOTS.*;
import org.omg.CORBA.CompletionStatus;
-import java.util.Enumeration;
+import java.util.*;
+
import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.BAD_PARAM;
@@ -88,17 +89,17 @@
/**
* OTS implementation class.
- *
+ *
* Implements both the Coordinator & Terminator interfaces of OTS as a single
* class.
- *
+ *
* Note, because Java does not support multiple inheritance we must make use of
* the tie facility (uuuggghhhh!!!!)
- *
+ *
* @author Mark Little (mark at arjuna.com)
* @version $Id: ArjunaTransactionImple.java 2342 2006-03-30 13:06:17Z $
* @since JTS 1.0.
- *
+ *
* @message com.arjuna.ats.internal.jts.orbspecific.coordinator.generror {0}
* caught exception: {1}
* @message com.arjuna.ats.internal.jts.orbspecific.coordinator.rbofail {0}
@@ -170,14 +171,14 @@
* Fully checked transactions only allow the thread which began the
* transaction to terminate it. We get the id of the beginning
* thread here.
- *
+ *
* The spec. says nothing about crash recovery, so we better assume
* it can always complete a transaction!
- *
+ *
* If the creating thread dies before terminating the transaction
* then we have a problem. Requires change to Thread class to abort
* outstanding transactions in this case.
- *
+ *
* Also, transaction timeouts cause abortion of the transaction by a
* *different* thread! This must work even in the presence of
* checked transactions!
@@ -322,7 +323,7 @@
* example) then we do nothing - could throw TransactionRequired or
* INVALID_TRANSACTION. However, if it was rolledback then we throw
* TRANSACTION_ROLLEDBACK. Seems like an inconsistency.
- *
+ *
* report_heuristics is ignored if we are a subtransaction.
*/
@@ -793,7 +794,7 @@
* Resources are only registered with the current transaction, whereas
* subtransaction aware resources are registered with their parents when the
* current transaction ends.
- *
+ *
* @message com.arjuna.ats.internal.jts.orbspecific.coordinator.rccreate
* Creation of RecoveryCoordinator for {0} threw: {1}
* @message com.arjuna.ats.internal.jts.orbspecific.coordinator.rcnotcreated
@@ -1239,12 +1240,35 @@
synchronized (this)
{
if (_synchs == null)
- _synchs = new HashList(10);
+ {
+ // Synchronizations should be stored (or at least iterated) in their natural order
+ _synchs = new TreeSet();
+ }
}
- SynchronizationRecord otsSync = new SynchronizationRecord(sync);
+ SynchronizationRecord otsSync;
- if (!_synchs.add(otsSync))
+ if(sync._is_a(JTAInterposedSynchronizationHelper.id()))
+ {
+ otsSync = new SynchronizationRecord(sync, true);
+ }
+ else
+ {
+ otsSync = new SynchronizationRecord(sync);
+ }
+
+ // disallow addition of Synchronizations that would appear
+ // earlier in sequence than any that has already been called
+ // during the pre-commmit phase. This is required for
+ // JTA 1.1 Synchronization ordering behaviour
+ if(_currentRecord != null) {
+ Comparable c = (Comparable)otsSync;
+ if(c.compareTo(_currentRecord) != 1) {
+ throw new UNKNOWN(ExceptionCodes.ADD_FAILED, CompletionStatus.COMPLETED_NO);
+ }
+ }
+
+ if (!_synchs.add(otsSync))
{
otsSync = null;
throw new UNKNOWN(ExceptionCodes.ADD_FAILED,
@@ -1414,7 +1438,7 @@
}
protected void doBeforeCompletion () throws SystemException
- {
+ {
if (jtsLogger.logger.isDebugEnabled())
{
jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PROTECTED, com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ArjunaTransactionImple::doBeforeCompletion for "
@@ -1427,11 +1451,8 @@
/*
* If we have a synchronization list then we must be top-level.
*/
-
- if (_synchs != null)
+ if (_synchs != null)
{
- HashListIterator iterator = new HashListIterator(_synchs);
- SynchronizationRecord value = (SynchronizationRecord) iterator.iterate();
boolean doSuspend = false;
ControlWrapper cw = null;
@@ -1474,13 +1495,29 @@
*/
}
- while (value != null)
- {
- Synchronization c = value.contents();
+ /*
+ * Since Synchronizations may add register other Synchronizations, we can't simply
+ * iterate the collection. Instead we work from an ordered copy, which we periodically
+ * check for freshness. The addSynchronization method uses _currentRecord to disallow
+ * adding records in the part of the array we have already traversed, thus all
+ * Synchronization will be called and the (jta only) rules on ordering of interposed
+ * Synchronization will be respected.
+ */
+ int lastIndexProcessed = -1;
+ SynchronizationRecord[] copiedSynchs = (SynchronizationRecord[])_synchs.toArray(new SynchronizationRecord[] {});
+ while( (lastIndexProcessed < _synchs.size()-1) && !problem) {
+
+ // if new Synchronization have been registered, refresh our copy of the collection:
+ if(copiedSynchs.length != _synchs.size()) {
+ copiedSynchs = (SynchronizationRecord[])_synchs.toArray(new SynchronizationRecord[] {});
+ }
+
+ lastIndexProcessed = lastIndexProcessed+1;
+ _currentRecord = copiedSynchs[lastIndexProcessed];
+
+ Synchronization c = _currentRecord.contents();
c.before_completion();
-
- value = (SynchronizationRecord) iterator.iterate();
}
}
catch (SystemException e)
@@ -1583,8 +1620,6 @@
if (_synchs != null)
{
- HashListIterator iterator = new HashListIterator(_synchs);
- SynchronizationRecord value = (SynchronizationRecord) iterator.iterate();
ControlWrapper cw = null;
boolean doSuspend = false;
@@ -1624,8 +1659,22 @@
* happened.
*/
- while (value != null)
+ // afterCompletions should run in reverse order compared to beforeCompletions
+ Stack stack = new Stack();
+ Iterator iterator = _synchs.iterator();
+ while(iterator.hasNext()) {
+ stack.push(iterator.next());
+ }
+
+ iterator = stack.iterator();
+
+ /*
+ * Regardless of failures, we must tell all synchronizations what
+ * happened.
+ */
+ while(!stack.isEmpty())
{
+ SynchronizationRecord value = (SynchronizationRecord)stack.pop();
Synchronization c = value.contents();
try
@@ -1651,8 +1700,6 @@
if (exp == null)
exp = e;
}
-
- value = (SynchronizationRecord) iterator.iterate();
}
if (doSuspend)
@@ -1825,7 +1872,7 @@
* If the resource is an ArjunaOTS.OTSAbstractRecord or an
* ArjunaOTS.ArjunaSubtranAwareResource then we can do better record
* manipulation, and proper nested actions.
- *
+ *
* Based on the type of resource we create the right abstract record to
* handle it, rather than a single abstract record which switches
* protocols internally.
@@ -1922,14 +1969,14 @@
/*
* The caller should delete the context.
- *
+ *
* The propagation context is specified on a per client thread basis.
* Therefore, at the server side we must maintain a hierarchy for each
* thread. However, the server cannot simply tear down this hierarchy
* whenever it receives a completely new one from the same thread, since the
* OTS lets a thread suspend/resume contexts at will. Potential for memory
* leaks in C++ version, but not Java!!
- *
+ *
* Currently we assume that the hierarchy will be JBoss transactions so we
* can get the parents of transactions. If it is not then we could simply
* just call get_txcontext on the control!
@@ -2279,9 +2326,10 @@
private BasicAction rootAction;
- private HashList _synchs;
+ private SortedSet _synchs;
+ private SynchronizationRecord _currentRecord; // the most recently processed Synchronization.
- static int _ipType = Arjuna.XID();
+ static int _ipType = Arjuna.XID();
static boolean _subtran = true;
Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/SynchronizationRecord.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/SynchronizationRecord.java 2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/SynchronizationRecord.java 2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a full listing
+ * 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 General Public License, v. 2.0.
- * 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
+ * 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 General Public License for more details.
* You should have received a copy of the GNU General Public License,
* v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
- *
+ *
* (C) 2005-2006,
* @author JBoss Inc.
*/
@@ -24,7 +24,7 @@
* Arjuna Solutions Limited,
* Newcastle upon Tyne,
* Tyne and Wear,
- * UK.
+ * UK.
*
* $Id: SynchronizationRecord.java 2342 2006-03-30 13:06:17Z $
*/
@@ -50,9 +50,9 @@
* @since JTS 1.0.
*/
-public class SynchronizationRecord implements ListElement
+public class SynchronizationRecord implements ListElement, Comparable
{
-
+
public SynchronizationRecord (Synchronization ptr)
{
if (jtsLogger.logger.isDebugEnabled())
@@ -63,8 +63,14 @@
_ptr = ptr;
_uid = new Uid();
+ _isJTAInterposed = false;
}
+ public SynchronizationRecord (Synchronization ptr, boolean isJTAInterposed) {
+ this(ptr);
+ _isJTAInterposed = isJTAInterposed;
+ }
+
public void finalize ()
{
if (jtsLogger.logger.isDebugEnabled())
@@ -93,7 +99,41 @@
return _uid;
}
+ /*
+ * SyncronizationsImples are ordered first according to the isJTAInterposed property and then by Uid.
+ * Interposed synchronizations must come after non-interposed ones (see
+ * TransactionSynchronizationRegistry) The ordering within the interposed/non-interposed categories
+ * is arbitrary but must be defined for correct functioning of the sort. Just don't rely on it in
+ * application level code.
+ *
+ * Note that interposition here is in the JTA TSR interface sense, not CORBA TS.
+ *
+ * @param object
+ * @return
+ */
+ public int compareTo(Object object)
+ {
+ SynchronizationRecord other = (SynchronizationRecord)object;
+
+ if(this._isJTAInterposed && (!other._isJTAInterposed))
+ {
+ return 1;
+ }
+ else if((!this._isJTAInterposed) && other._isJTAInterposed)
+ {
+ return -1;
+ }
+ else if(this._uid.equals(other._uid))
+ {
+ return 0;
+ }
+ else
+ {
+ return this._uid.lessThan(other._uid) ? -1 : 1;
+ }
+ }
+
private Uid _uid;
private Synchronization _ptr;
-
+ private boolean _isJTAInterposed;
}
Modified: labs/jbosstm/trunk/ArjunaJTS/jts/idl/arjuna/ArjunaOTS.idl
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/idl/arjuna/ArjunaOTS.idl 2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/idl/arjuna/ArjunaOTS.idl 2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a full listing
+ * 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 General Public License, v. 2.0.
- * 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
+ * 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 General Public License for more details.
* You should have received a copy of the GNU General Public License,
* v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
- *
+ *
* (C) 2005-2006,
* @author JBoss Inc.
*/
@@ -63,7 +63,7 @@
long timeout;
long numberOfThreads;
};
-
+
typedef sequence<CosTransactions::otid_t> txIds;
// Some useful exceptions
@@ -133,7 +133,7 @@
boolean propagateOnCommit ();
boolean saveRecord ();
-
+
void merge (in OTSAbstractRecord record);
void alter (in OTSAbstractRecord record);
@@ -142,6 +142,12 @@
boolean shouldMerge (in OTSAbstractRecord record);
boolean shouldReplace (in OTSAbstractRecord record);
};
+
+ // for JTA 1.1 TransactionSynchronizationRegistry support, a marker interface
+ // for Interposed (in the JTA rather than CORBA sense) Synchronizations
+ interface JTAInterposedSynchronization : CosTransactions::Synchronization
+ {
+ };
};
#endif
More information about the jboss-svn-commits
mailing list