User: fleury
Date: 00/08/10 20:00:56
Modified: src/main/org/jboss/tm TransactionImpl.java TxManager.java
Log:
The new and improved TM
The "public" face is still the TransactionImpl but that is a lightweight object.
All the callbacks are held in the "TxCapsule" which is an aggregate of all things
pertaining to the Tx. That capsules never leaves the VM and is accessed under the key
of the transaction through the Transaction Monitor.
The TransactionImpl is serializable (like really :) and the TxCapsule does the work
the TxImpl used to do.
It allows to have many Tx objects (b2b serialized calls) in one VM that all point to
the same "TxCapsule".
Revision Changes Path
1.6 +35 -179 jboss/src/main/org/jboss/tm/TransactionImpl.java
Index: TransactionImpl.java
===================================================================
RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/tm/TransactionImpl.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- TransactionImpl.java 2000/07/27 22:24:52 1.5
+++ TransactionImpl.java 2000/08/11 03:00:54 1.6
@@ -25,11 +25,15 @@
import javax.transaction.xa.XAException;
/**
- * <description>
+ * A light weight transaction.
*
+ * It is the public face of the TxCapsule. Many of these "transactions" can
coexist representing the TxCap
+ * Access to the underlying txCap is done through the TransactionManager
+ *
* @see <related>
* @author Rickard �berg ([EMAIL PROTECTED])
- * @version $Revision: 1.5 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
+ * @version $Revision: 1.6 $
*/
public class TransactionImpl
implements Transaction, Serializable
@@ -37,55 +41,35 @@
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
- Vector sync;
- Vector resources;
-
- Xid xid;
- int status;
- long timeout;
- long start;
-
+ int hash;
+ Xid xid; // XA legacy
+
// Static --------------------------------------------------------
- static long nextId = 0;
- public long getNextId() { return nextId++; }
public transient TxManager tm;
static String hostName;
// Constructors --------------------------------------------------
- public TransactionImpl(TxManager tm, int timeout)
- {
- this(tm);
-
- resources = new Vector();
- sync = new Vector();
- status = Status.STATUS_ACTIVE;
-
- this.timeout = (long)timeout;
- start = System.currentTimeMillis();
- }
-
- public TransactionImpl(TxManager tm)
+
+ public TransactionImpl(TxManager tm,int hash, Xid xid)
{
- status = Status.STATUS_NO_TRANSACTION;
- xid = new XidImpl((getHostName()+"/"+getNextId()).getBytes(), null);
-
this.tm = tm;
+ this.hash = hash;
+ this.xid = xid;
}
- private TxManager getTxManager() {
-
- if (tm != null) {
-
- return tm;
- }
-
- // A way to circle the mess
- // :(
- tm = TxManager.getTransactionManager();
+ /*
+ * setTxManager()
+ *
+ * used for propagated Tx
+ */
+ public void setTxManager(TxManager tm) {
- return tm;
+ this.tm= tm;
}
+
+
+
// Public --------------------------------------------------------
public void commit()
@@ -96,148 +80,29 @@
java.lang.IllegalStateException,
SystemException
{
- if (status == Status.STATUS_NO_TRANSACTION)
- throw new IllegalStateException("No transaction started");
- // Call Synchronization
- for (int i = 0; i < sync.size(); i++)
- {
- // Check rollback
- if (status == Status.STATUS_MARKED_ROLLBACK)
- {
- break;
- }
-
- ((Synchronization)sync.elementAt(i)).beforeCompletion();
- }
-
- // Check rollback
- if (status != Status.STATUS_MARKED_ROLLBACK)
- {
- // Prepare XAResources
- status = Status.STATUS_PREPARING;
- for (int i = 0; i < resources.size(); i++)
- {
- // Check rollback
- if (status == Status.STATUS_MARKED_ROLLBACK)
- {
- break;
- }
-
- try
- {
- ((XAResource)resources.elementAt(i)).prepare(xid);
- } catch (XAException e)
- {
- if(e.errorCode != XAException.XA_HEURCOM)
- {
- e.printStackTrace();
- // Rollback
- setRollbackOnly();
- break;
- }
- }
- }
-
- // Check rollback
- if (status != Status.STATUS_MARKED_ROLLBACK)
- {
- status = Status.STATUS_PREPARED; // TODO: necessary to set?
-
- // Commit XAResources
- status = Status.STATUS_COMMITTING;
- for (int i = 0; i < resources.size(); i++)
- {
-
- try
- {
- ((XAResource)resources.elementAt(i)).commit(xid, false);
- } catch (XAException e)
- {
- try {
- ((XAResource)resources.elementAt(i)).forget(xid);
- } catch(XAException another) {}
- e.printStackTrace();
- // TODO: what to do here?
- }
- }
- status = Status.STATUS_COMMITTED;
- }
- }
-
- // Check rollback
- if (status == Status.STATUS_MARKED_ROLLBACK)
- {
- // Rollback XAResources
- status = Status.STATUS_ROLLING_BACK;
- for (int i = 0; i < resources.size(); i++)
- {
-
- try
- {
- ((XAResource)resources.elementAt(i)).rollback(xid);
- } catch (XAException e)
- {
- try {
- ((XAResource)resources.elementAt(i)).forget(xid);
- } catch(XAException another) {}
- // TODO: what to do here?
- }
- }
- status = Status.STATUS_ROLLEDBACK;
- }
-
- // Call Synchronization
- for (int i = 0; i < sync.size(); i++)
- {
- ((Synchronization)sync.elementAt(i)).afterCompletion(status);
- }
-
- // Remove thread association with this tx
- getTxManager().removeTransaction();
- resources.clear();
+ tm.commit(this);
}
public boolean delistResource(XAResource xaRes, int flag)
{
- try {
- xaRes.end(xid, Status.STATUS_ACTIVE);
-// resources.removeElement(xaRes);
- return true;
- } catch(XAException e) {
- e.printStackTrace();
- return false;
- }
+ return tm.delistResource(this, xaRes, flag);
}
public boolean enlistResource(XAResource xaRes)
throws RollbackException
{
- // Check rollback only
- if (status == Status.STATUS_MARKED_ROLLBACK)
- {
- throw new RollbackException();
- }
-
- // Add resource
- try {
- xaRes.start(xid, Status.STATUS_ACTIVE);
- resources.addElement(xaRes);
- return true;
- } catch(XAException e) {
- e.printStackTrace();
- return false;
- }
+ return tm.enlistResource(this, xaRes);
}
public int getStatus()
throws SystemException
{
- return status;
+ return tm.getStatus(this);
}
public void registerSynchronization(Synchronization s)
{
- sync.addElement(s);
+ tm.registerSynchronization(this, s);
}
public void rollback()
@@ -245,28 +110,25 @@
java.lang.SecurityException,
SystemException
{
- if (status == Status.STATUS_NO_TRANSACTION)
- throw new IllegalStateException("No transaction started");
+ tm.rollback(this);
}
public void setRollbackOnly()
throws java.lang.IllegalStateException,
SystemException
{
- if (status == Status.STATUS_NO_TRANSACTION)
- throw new IllegalStateException("No transaction started");
-
- status = Status.STATUS_MARKED_ROLLBACK;
- }
+
+ tm.setRollbackOnly(this);
+ }
public boolean equals(Object obj)
{
- return ((TransactionImpl)obj).xid.equals(xid);
+ return ((TransactionImpl)obj).hash == hash;
}
public int hashCode()
{
- return xid.getGlobalTransactionId().hashCode();
+ return hash;
}
// Package protected ---------------------------------------------
@@ -289,15 +151,9 @@
}
public String toString() {
- return xid.toString();
+ return "tx:Xid:"+hash;
}
// Private -------------------------------------------------------
-/* private Object writeReplace(java.io.ObjectOutputStream out)
- throws IOException
- {
- return new TransactionProxy(this);
- }
-*/
// Inner classes -------------------------------------------------
}
1.6 +120 -43 jboss/src/main/org/jboss/tm/TxManager.java
Index: TxManager.java
===================================================================
RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/tm/TxManager.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- TxManager.java 2000/07/28 00:25:18 1.5
+++ TxManager.java 2000/08/11 03:00:54 1.6
@@ -6,8 +6,11 @@
*/
package org.jboss.tm;
+import java.util.Hashtable;
+
import javax.transaction.Status;
import javax.transaction.TransactionManager;
+import javax.transaction.Synchronization;
import javax.transaction.Transaction;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
@@ -15,6 +18,10 @@
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.InvalidTransactionException;
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.XAException;
+
import org.jboss.logging.Logger;
@@ -23,7 +30,8 @@
*
* @see <related>
* @author Rickard �berg ([EMAIL PROTECTED])
- * @version $Revision: 1.5 $
+ * @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
+ * @version $Revision: 1.6 $
*/
public class TxManager
implements TransactionManager
@@ -31,9 +39,11 @@
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
- ThreadLocal tx = new ThreadLocal();
- Transaction noTx = new TransactionImpl(null);
-
+ // threadTx keeps track of a thread local association of tx
+ ThreadLocal threadTx = new ThreadLocal();
+ // transactions maps
+ Hashtable txCapsules = new Hashtable();
+
int timeOut = 60*1000; // Timeout in milliseconds
// Static --------------------------------------------------------
@@ -45,7 +55,15 @@
throws NotSupportedException,SystemException
{
// System.out.println("begin tx");
- tx.set(new TransactionImpl(this, timeOut));
+
+ // create tx capsule
+ TxCapsule txCap = new TxCapsule(this, timeOut);
+
+ // Store it
+ txCapsules.put(txCap.getTransaction(), txCap);
+
+ // Associate it with the Thread
+ threadTx.set(txCap.getTransaction());
}
public void commit()
@@ -57,47 +75,60 @@
SystemException
{
// System.out.println("commit tx");
- getTransaction().commit();
+
+ try {
+
+ getTransaction().commit();
+ }
+ finally {
+
+ // Disassociation
+ threadTx.set(null);
+ }
}
public int getStatus()
throws SystemException
{
- Transaction current = getTransaction();
- if (current == null)
+ // Get the txCapsule running now with the thread
+ TxCapsule txCap = (TxCapsule) txCapsules.get(threadTx.get());
+
+ if (txCap == null)
return Status.STATUS_NO_TRANSACTION;
else
- return current.getStatus();
+ return txCap.getStatus();
}
public Transaction getTransaction()
throws SystemException
{
- Transaction current = (Transaction)tx.get();
-
-//DEBUG Logger.debug("Current="+current);
+ return (Transaction)threadTx.get();
- // if (current == null)
-
- // MF FIXME
- // WHY?????
- // return noTx;
- // else
- return current;
}
- // FIXME MF: resume has another meaning
- // it means "resume the suspended transaction"
- // Not resume the association with thread
public void resume(Transaction tobj)
throws InvalidTransactionException,
java.lang.IllegalStateException,
SystemException
{
-// Logger.debug("resume tx with "+tobj);
- tx.set(tobj);
+ //Useless
+
+ //throw new Exception("txMan.resume() NYI");
}
+
+ public Transaction suspend()
+ throws SystemException
+ {
+// System.out.println("suspend tx");
+
+ // Useless
+
+ return null;
+ //throw new Exception("txMan.suspend() NYI");
+ }
+
+
public void rollback()
throws java.lang.IllegalStateException,
java.lang.SecurityException,
@@ -121,42 +152,26 @@
timeOut = seconds;
}
- public Transaction suspend()
- throws SystemException
- {
-// System.out.println("suspend tx");
-
- Transaction current = (Transaction)tx.get();
- tx.set(null);
-
- return current;
- }
-
/*
* The following 2 methods are here to provide association and disassociation of
the thread
*/
public Transaction disassociateThread() {
- Transaction current = (Transaction) tx.get();
+ Transaction current = (Transaction) threadTx.get();
- tx.set(null);
+ threadTx.set(null);
return current;
}
public void associateThread(Transaction transaction) {
- tx.set(transaction);
+ threadTx.set(transaction);
}
// Package protected ---------------------------------------------
- void removeTransaction()
- {
- tx.set(null);
- }
-
// There has got to be something better :)
static TxManager getTransactionManager() {
@@ -177,7 +192,69 @@
{
return timeOut;
}
+
+
+
+
+ // Public --------------------------------------------------------
+ public void commit(Transaction tx)
+ throws RollbackException,
+ HeuristicMixedException,
+ HeuristicRollbackException,
+ java.lang.SecurityException,
+ java.lang.IllegalStateException,
+ SystemException
+ {
+ // Look up the txCapsule and delegate
+ ((TxCapsule) txCapsules.get(tx)).commit();
+ }
+
+ public boolean delistResource(Transaction tx, XAResource xaRes, int flag)
+ {
+ // Look up the txCapsule and delegate
+ return ((TxCapsule) txCapsules.get(tx)).delistResource(xaRes, flag);
+ }
+ public boolean enlistResource(Transaction tx, XAResource xaRes)
+ throws RollbackException
+ {
+ // Look up the txCapsule and delegate
+ return ((TxCapsule) txCapsules.get(tx)).enlistResource(xaRes);
+ }
+
+ public int getStatus(Transaction tx)
+ throws SystemException
+ {
+ // Look up the txCapsule and delegate
+ return ((TxCapsule) txCapsules.get(tx)).getStatus();
+ }
+
+ public void registerSynchronization(Transaction tx, Synchronization s)
+ {
+ // Look up the txCapsule and delegate
+ ((TxCapsule) txCapsules.get(tx)).registerSynchronization(s);
+ }
+
+ public void rollback(Transaction tx)
+ throws java.lang.IllegalStateException,
+ java.lang.SecurityException,
+ SystemException
+ {
+ // Look up the txCapsule and delegate
+ ((TxCapsule) txCapsules.get(tx)).rollback();
+ }
+
+ public void setRollbackOnly(Transaction tx)
+ throws java.lang.IllegalStateException,
+ SystemException
+ {
+ // Look up the txCapsule and delegate
+ ((TxCapsule) txCapsules.get(tx)).setRollbackOnly();
+
+ }
+
+
+
// Protected -----------------------------------------------------
// Private -------------------------------------------------------