User: mulder
Date: 00/07/03 17:14:36
Modified: src/main/org/jboss/tm TransactionImpl.java
Log:
Fixes to transaction handling.
- Call start and end when an XAResource is enlisted or delisted.
- Don't remove an XAResource from the list when it is delisted (it must still be
committed/rolled back).
- Call forget after a failed commit or rollback.
- Don't count a heuristic commit as an error when trying to commit.
NOTE: I probably didn't use the correct constants for start and end (didn't
have a spec on me at the time!)
Revision Changes Path
1.3 +73 -48 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.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TransactionImpl.java 2000/05/30 18:32:30 1.2
+++ TransactionImpl.java 2000/07/04 00:14:36 1.3
@@ -25,54 +25,54 @@
import javax.transaction.xa.XAException;
/**
- * <description>
- *
+ * <description>
+ *
* @see <related>
* @author Rickard �berg ([EMAIL PROTECTED])
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.3 $
*/
public class TransactionImpl
implements Transaction, Serializable
{
// Constants -----------------------------------------------------
-
+
// Attributes ----------------------------------------------------
Vector sync;
Vector resources;
-
+
Xid xid;
int status;
long timeout;
long start;
-
+
// Static --------------------------------------------------------
static long nextId = 0;
public long getNextId() { return nextId++; }
public 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)
{
status = Status.STATUS_NO_TRANSACTION;
xid = new XidImpl((getHostName()+"/"+getNextId()).getBytes(), null);
-
+
this.tm = tm;
}
-
+
// Public --------------------------------------------------------
public void commit()
throws RollbackException,
@@ -84,7 +84,6 @@
{
if (status == Status.STATUS_NO_TRANSACTION)
throw new IllegalStateException("No transaction started");
-
// Call Synchronization
for (int i = 0; i < sync.size(); i++)
{
@@ -93,10 +92,10 @@
{
break;
}
-
+
((Synchronization)sync.elementAt(i)).beforeCompletion();
}
-
+
// Check rollback
if (status != Status.STATUS_MARKED_ROLLBACK)
{
@@ -109,40 +108,48 @@
{
break;
}
-
+
try
{
((XAResource)resources.elementAt(i)).prepare(xid);
} catch (XAException e)
{
- // Rollback
- setRollbackOnly();
- break;
+ 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)
{
@@ -150,35 +157,44 @@
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
tm.removeTransaction();
+ resources.clear();
}
-
+
public boolean delistResource(XAResource xaRes, int flag)
{
- resources.removeElement(xaRes);
-
- return true;
+ try {
+ xaRes.end(xid, Status.STATUS_ACTIVE);
+// resources.removeElement(xaRes);
+ return true;
+ } catch(XAException e) {
+ e.printStackTrace();
+ return false;
+ }
}
-
+
public boolean enlistResource(XAResource xaRes)
throws RollbackException
{
@@ -187,24 +203,29 @@
{
throw new RollbackException();
}
-
+
// Add resource
- resources.addElement(xaRes);
-
- return true;
+ try {
+ xaRes.start(xid, Status.STATUS_ACTIVE);
+ resources.addElement(xaRes);
+ return true;
+ } catch(XAException e) {
+ e.printStackTrace();
+ return false;
+ }
}
-
+
public int getStatus()
throws SystemException
{
return status;
}
-
+
public void registerSynchronization(Synchronization s)
{
sync.addElement(s);
}
-
+
public void rollback()
throws java.lang.IllegalStateException,
java.lang.SecurityException,
@@ -213,29 +234,29 @@
if (status == Status.STATUS_NO_TRANSACTION)
throw new IllegalStateException("No transaction started");
}
-
+
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;
}
-
+
public boolean equals(Object obj)
{
return
((TransactionImpl)obj).xid.getGlobalTransactionId().equals(xid.getGlobalTransactionId());
}
-
+
public int hashCode()
{
return xid.getGlobalTransactionId().hashCode();
}
-
+
// Package protected ---------------------------------------------
-
+
// Protected -----------------------------------------------------
protected String getHostName()
{
@@ -249,16 +270,20 @@
hostName = "localhost";
}
}
-
+
return hostName;
}
-
+
+ public String toString() {
+ return xid.toString();
+ }
+
// Private -------------------------------------------------------
/* private Object writeReplace(java.io.ObjectOutputStream out)
throws IOException
{
return new TransactionProxy(this);
}
-*/
+*/
// Inner classes -------------------------------------------------
}