[Mulgara-svn] r1482 - trunk/src/jar/resolver/java/org/mulgara/resolver

ronald at mulgara.org ronald at mulgara.org
Thu Feb 12 17:59:57 UTC 2009


Author: ronald
Date: 2009-02-12 09:59:56 -0800 (Thu, 12 Feb 2009)
New Revision: 1482

Modified:
   trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransaction.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
Log:
Attempting to improve reporting of heuristic rollbacks to application by keeping
track of the cause for the last error and including that in the exceptions.

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java	2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransaction.java	2009-02-12 17:59:56 UTC (rev 1482)
@@ -147,7 +147,7 @@
         return new MulgaraTransactionException(errorMessage, cause);
       } finally {
         completed = true;
-        factory.transactionComplete(this);
+        factory.transactionComplete(this, rollbackCause);
       }
     } finally {
       releaseMutex();
@@ -469,6 +469,10 @@
     return heurCode;
   }
 
+  String getRollbackCause() {
+    return rollbackCause;
+  }
+
   boolean isRollbacked() {
     return rollback;
   }
@@ -604,7 +608,7 @@
   private void cleanupTransaction() throws XAException {
     report("cleanupTransaction");
     try {
-      factory.transactionComplete(this);
+      factory.transactionComplete(this, rollbackCause);
     } catch (MulgaraTransactionException em) {
       try {
         logger.error("Failed to cleanup transaction", em);

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java	2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraExternalTransactionFactory.java	2009-02-12 17:59:56 UTC (rev 1482)
@@ -48,11 +48,13 @@
   private final MulgaraXAResourceContext xaResource;
 
   private MulgaraExternalTransaction associatedTransaction;
+  private String                     lastRollbackCause;
 
   public MulgaraExternalTransactionFactory(DatabaseSession session, MulgaraTransactionManager manager) {
     super(session, manager);
 
     this.associatedTransaction = null;
+    this.lastRollbackCause = null;
     this.transactions = new HashSet<MulgaraExternalTransaction>();
     this.xaResource = new MulgaraXAResourceContext(this, session);
   }
@@ -61,7 +63,10 @@
     acquireMutex(0, MulgaraTransactionException.class);
     try {
       if (associatedTransaction == null) {
-        throw new MulgaraTransactionException("No externally mediated transaction associated with session");
+        throw new MulgaraTransactionException(
+            "No externally mediated transaction associated with session" +
+            (lastRollbackCause != null ? " - last transaction was rolled back with error: " +
+                                         lastRollbackCause : ""));
       } else if (write && associatedTransaction != writeTransaction) {
         throw new MulgaraTransactionException("RO-transaction associated with session when requesting write operation");
       }
@@ -91,6 +96,7 @@
           xa = new MulgaraExternalTransaction(this, xid, session.newOperationContext(true));
           writeTransaction = xa;
           associatedTransaction = xa;
+          lastRollbackCause = null;
           transactions.add(xa);
           transactionCreated(xa);
 
@@ -98,13 +104,14 @@
         } catch (Throwable th) {
           manager.releaseWriteLock(session);
           if (xa != null)
-            transactionComplete(xa);
+            transactionComplete(xa, th.toString());
           throw new MulgaraTransactionException("Error initiating write transaction", th);
         }
       } else {
         try {
           MulgaraExternalTransaction xa = new MulgaraExternalTransaction(this, xid, session.newOperationContext(false));
           associatedTransaction = xa;
+          lastRollbackCause = null;
           transactions.add(xa);
           transactionCreated(xa);
 
@@ -131,7 +138,7 @@
     }
   }
 
-  public void transactionComplete(MulgaraExternalTransaction xa)
+  public void transactionComplete(MulgaraExternalTransaction xa, String rollbackCause)
       throws MulgaraTransactionException {
     acquireMutex(0, MulgaraTransactionException.class);
     try {
@@ -147,6 +154,7 @@
       transactions.remove(xa);
       if (associatedTransaction == xa) {
         associatedTransaction = null;
+        lastRollbackCause = rollbackCause;
       }
     } finally {
       releaseMutex();

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransaction.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransaction.java	2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransaction.java	2009-02-12 17:59:56 UTC (rev 1482)
@@ -512,7 +512,7 @@
             context.clear();
             enlisted.clear();
             state = State.FAILED;
-            factory.transactionAborted(this);
+            factory.transactionAborted(this, rollbackCause);
             return new MulgaraTransactionException("Transaction rollback triggered", cause);
         case DEACTREF:
           throw new IllegalStateException("Attempt to rollback deactivated transaction");
@@ -567,6 +567,8 @@
       // need to rollback this transaction, but if we have reached here
       // we have failed to obtain a valid transaction to rollback!
       try {
+        if (rollbackCause == null) rollbackCause = cause;
+
         try {
           errorReport(errorMessage + " - Aborting", cause);
         } finally { try {
@@ -574,7 +576,7 @@
             transaction.rollback();
           }
         } finally { try {
-          factory.transactionAborted(this);
+          factory.transactionAborted(this, cause);
         } finally { try {
           abortEnlistedResources();
         } finally { try {

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java	2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraInternalTransactionFactory.java	2009-02-12 17:59:56 UTC (rev 1482)
@@ -56,9 +56,12 @@
   private static final Logger logger =
     Logger.getLogger(MulgaraInternalTransactionFactory.class.getName());
 
-  /** Set of sessions whose transactions have been rolledback.*/
+  /** Flag indicating current explicit-transaction has been rolledback. */
   private boolean isFailed;
 
+  /** The reason for the failure if {@link #isFailed} is true. */
+  private Throwable failureCause;
+
   /** Map of threads to active transactions. */
   private final Map<Thread, MulgaraTransaction> activeTransactions;
 
@@ -78,6 +81,7 @@
     super(session, manager);
 
     this.isFailed = false;
+    this.failureCause = null;
     this.activeTransactions = new HashMap<Thread, MulgaraTransaction>();
     this.autoCommit = true;
     this.transactions = new HashSet<MulgaraTransaction>();
@@ -141,7 +145,8 @@
     acquireMutex(0, MulgaraTransactionException.class);
     try {
       if (isFailed) {
-        throw new MulgaraTransactionException("Attempting to commit failed session");
+        if (failureCause != null) throw new MulgaraTransactionException("Attempting to commit failed session", failureCause);
+        else throw new MulgaraTransactionException("Attempting to commit failed session");
       } else if (!manager.isHoldingWriteLock(session)) {
         throw new MulgaraTransactionException(
             "Attempting to commit while not the current writing transaction");
@@ -194,6 +199,7 @@
       } else if (isFailed) {
         explicitXA = null;
         isFailed = false;
+        failureCause = null;
         setAutoCommit(false);
       } else {
         throw new MulgaraTransactionException(
@@ -238,6 +244,7 @@
           } else if (isFailed) {
             // Within failed transaction - cleanup.
             isFailed = false;
+            failureCause = null;
           }
         } else {
           if (!manager.isHoldingWriteLock(session)) {
@@ -387,13 +394,14 @@
     }
   }
 
-  public void transactionAborted(MulgaraTransaction transaction) {
+  public void transactionAborted(MulgaraTransaction transaction, Throwable cause) {
     acquireMutex(0, RuntimeException.class);
     try {
       try {
         // Make sure this cleans up the transaction metadata - this transaction is DEAD!
         if (!autoCommit && transaction == writeTransaction) {
           isFailed = true;
+          failureCause = cause;
         }
         transactionComplete(transaction);
       } catch (Throwable th) {

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java	2009-02-12 17:59:50 UTC (rev 1481)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java	2009-02-12 17:59:56 UTC (rev 1482)
@@ -124,8 +124,8 @@
           // 7.6.2.2 requires an XA_RB* exception in the case of 1PC and 7.6.2.5
           // implies that HEURRB is not permitted during 2PC - this seems broken
           // to me, but that's the spec.
-//          throw new XAException(XAException.XA_HEURRB);
-          throw new XAException(XAException.XA_RBROLLBACK);
+//          throw newXAException(XAException.XA_HEURRB, xa.getRollbackCause());
+          throw newXAException(XAException.XA_RBROLLBACK, xa.getRollbackCause());
         } else if (xa.isHeuristicallyCommitted()) {
           throw new XAException(XAException.XA_HEURCOM);
         }
@@ -191,7 +191,7 @@
             break;
           case TMSUCCESS:
             if (xa.isHeuristicallyRollbacked()) {
-              throw new XAException(XAException.XA_RBPROTO);
+              throw newXAException(XAException.XA_RBPROTO, xa.getRollbackCause());
             }
             break;
           case TMSUSPEND: // Should I be tracking the xid's state to ensure
@@ -330,8 +330,9 @@
      */
     private void doRollback(MulgaraExternalTransaction xa, Xid xid) throws XAException {
       if (xa.isHeuristicallyRollbacked()) {
-        logger.warn("Attempted to rollback heuristically rollbacked transaction: " + xa.getHeuristicCode());
-        throw new XAException(xa.getHeuristicCode());
+        logger.warn("Attempted to rollback heuristically rollbacked transaction: xa-code=" +
+                    xa.getHeuristicCode() + ", reason-string='" + xa.getRollbackCause() + "'");
+        throw newXAException(xa.getHeuristicCode(), xa.getRollbackCause());
       } else if (!xa.isRollbacked()) {
         xa.rollback(xid);
       }
@@ -413,6 +414,12 @@
     private DatabaseSession getSession() { return session; }
   }
 
+  private static XAException newXAException(int errorCode, String reason) {
+    XAException xae = new XAException(reason);
+    xae.errorCode = errorCode;
+    return xae;
+  }
+
   public static String parseXid(Xid xid) {
     return xid.toString();
   }




More information about the Mulgara-svn mailing list