[Mulgara-svn] r569 - branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver

andrae at mulgara.org andrae at mulgara.org
Wed Nov 21 11:12:45 UTC 2007


Author: andrae
Date: 2007-11-21 05:12:44 -0600 (Wed, 21 Nov 2007)
New Revision: 569

Modified:
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java
Log:
Next increment towards proper handling of rollbacks.
Also includes several interface/compile-error fixes.



Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java	2007-11-21 11:11:27 UTC (rev 568)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java	2007-11-21 11:12:44 UTC (rev 569)
@@ -18,6 +18,13 @@
 package org.mulgara.resolver;
 
 // Java 2 enterprise packages
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
 
 // Third party packages
 import org.apache.log4j.Logger;
@@ -43,6 +50,9 @@
  * @licence Open Software License v3.0
  */
 public class MulgaraExternalTransaction implements MulgaraTransaction {
+  private static final Logger logger =
+    Logger.getLogger(MulgaraExternalTransaction.class.getName());
+
   private Xid xid;
 
   private Set<EnlistableResource> enlisted;
@@ -53,7 +63,11 @@
   private MulgaraExternalTransactionFactory factory;
   private DatabaseOperationContext context;
 
-  MulgaraExternalTransaction(MulgaraExternalTransactionFactory resource, OperationContext context) {
+  private boolean hRollback;
+  private int heurCode;
+  private boolean rollback;
+
+  MulgaraExternalTransaction(MulgaraExternalTransactionFactory resource, DatabaseOperationContext context) {
     this.factory = factory;
     this.context = context;
 
@@ -61,63 +75,96 @@
     this.prepared = new HashSet<EnlistableResource>();
     this.committed = new HashSet<EnlistableResource>();
     this.rollbacked = new HashSet<EnlistableResource>();
+
+    this.hRollback = false;
+    this.heurCode = 0;
+    this.rollback = false;
   }
 
   // We ignore reference counting in external transactions
-  void reference() throws MulgaraTransactionException {}  
-  void dereference() throws MulgaraTransactionException {}
+  public void reference() throws MulgaraTransactionException {}  
+  public void dereference() throws MulgaraTransactionException {}
 
-  MulgaraTransactionException abortTransaction(String errorMessage, Throwable cause)
+  public MulgaraTransactionException abortTransaction(String errorMessage, Throwable cause)
       throws MulgaraTransactionException {
     try {
-      if (resource.getStatus() == MulgaraXAResource.ACTIVE) {
-        resource.setRollback(cause);
+      for (EnlistableResource resource : enlisted) {
+        try {
+          resource.abort();
+        } catch (Throwable throw_away) {}
       }
-      for (EnlistableResource resource : resources) {
+      for (EnlistableResource resource : prepared) {
         try {
           resource.abort();
         } catch (Throwable throw_away) {}
       }
+
+      return new MulgaraTransactionException(errorMessage, cause);
     } finally {
       cleanupTransaction();
     }
   }
 
+  public void heuristicRollback(String cause) throws MulgaraTransactionException {
+    hRollback = true;
+    try {
+      rollback(xid);
+    } catch (XAException xa) {
+      throw new MulgaraTransactionException("Failed heuristic rollback", xa);
+    } finally {
+      heurCode = heurCode == 0 ? XAException.XA_HEURRB : heurCode;
+    }
+  }
 
-  void execute(Operation operation,
+  public void execute(Operation operation,
                ResolverSessionFactory resolverSessionFactory,
                DatabaseMetadata metadata) throws MulgaraTransactionException {
-    if (resource.getStatus() != MulgaraXAResource.ACTIVE) {
-      throw new MulgaraTransactionException("Invalid transactional context : " + resource.getStatus());
-    }
+    // FIXME: Do I need to check that this transaction is 'active' ?
     try {
       operation.execute(context,
                         context.getSystemResolver(),
                         resolverSessionFactory,
                         metadata);
     } catch (Throwable th) {
-      resource.setRollback(th);
+      try {
+        rollback(xid);
+      } catch (XAException ex) {
+        logger.error("Error in rollback after operation failure", ex);
+      }
       throw new MulgaraTransactionException("Operation failed", th);
     }
   }
 
-  AnswerOperationResult execute(AnswerOperation ao) throws TuplesException {
-    if (resource.getStatus() != MulgaraXAResource.ACTIVE) {
-      throw new TuplesException("Invalid transactional context : " + resource.getStatus());
-    }
+  public AnswerOperationResult execute(AnswerOperation ao) throws TuplesException {
     try {
-      return ao.execute();
+      ao.execute();
+      return ao.getResult();
     } catch (Throwable th) {
-      resource.setRollback(th);
+      try {
+        rollback(xid);
+      } catch (XAException ex) {
+        logger.error("Error in rollback after answer-operation failure", ex);
+      }
       throw new TuplesException("Request failed", th);
     }
   }
 
+  // FIXME: See if we can't rearrange things to allow this to be deleted.
+  public void execute(TransactionOperation to) throws MulgaraTransactionException {
+    throw new MulgaraTransactionException("Not Implemented: shouldn't be required");
+  }
+
   public void enlist(EnlistableResource enlistable) throws MulgaraTransactionException {
-    if (!resources.contains(enlistable)) {
-      XAResource res = enlistable.getXAResource();
-      bringUptodate(res);
-      resources.add(enlistable);
+    try {
+      if (!enlisted.contains(enlistable)) {
+        enlisted.add(enlistable);
+        XAResource res = enlistable.getXAResource();
+        // FIXME: We need to handle this uptodate operation properly.
+        // bringUptodate(res);
+        res.start(xid, XAResource.TMNOFLAGS);
+      }
+    } catch (XAException ex) {
+      throw new MulgaraTransactionException("Failed to enlist resource", ex);
     }
   }
 
@@ -126,7 +173,8 @@
   //
 
   void commit(Xid xid) throws XAException {
-    for (EnlistableResource er : xa.getEnlistedResources()) {
+    // FIXME: Consider the possiblity prepare failed, or was incomplete.
+    for (EnlistableResource er : prepared) {
       er.getXAResource().commit(xid, false);
       committed.add(er);
     }
@@ -134,15 +182,19 @@
   }
 
   boolean isHeuristicallyRollbacked() {
-    return false;
+    return hRollback;
   }
 
   boolean isHeuristicallyCommitted() {
     return false;
   }
 
+  boolean isRollbacked() {
+    return rollback;
+  }
+
   void prepare(Xid xid) throws XAException {
-    for (EnlistableResource er : xa.getEnlistedResources()) {
+    for (EnlistableResource er : enlisted) {
       er.getXAResource().prepare(xid);
       prepared.add(er);
     }
@@ -151,14 +203,13 @@
 
   void rollback(Xid xid) throws XAException {
     try {
+      rollback = true;
       Map<EnlistableResource, XAException> rollbackFailed = new HashMap<EnlistableResource, XAException>();
 
-      assert exception != null;
-
-      for (EnlistableResource er : xa.getEnlistedResources()) {
+      for (EnlistableResource er : enlisted) {
         try {
           if (!committed.contains(er)) {
-            er.getXAResource().rollback(xid, false);
+            er.getXAResource().rollback(xid);
             rollbacked.add(er);
           }
         } catch (XAException ex) {
@@ -189,7 +240,7 @@
               // All these amount to not knowing the result - so we have a hazard
               // unless we already know we have a mixed result.
               if (heurCode != XAException.XA_HEURMIX) {
-                XAException.XA_HEURHAZ;
+                heurCode = XAException.XA_HEURHAZ;
               }
               break;
             case XAException.XA_HEURCOM:
@@ -225,10 +276,6 @@
     }
   }
 
-  boolean isRollbackOnly() {
-    return rollbackOnly;
-  }
-
   private void cleanupTransaction() {
     factory.transactionComplete(this);
   }




More information about the Mulgara-svn mailing list