geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject svn commit: r1684215 - /geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java
Date Mon, 08 Jun 2015 16:10:50 GMT
Author: gnodet
Date: Mon Jun  8 16:10:49 2015
New Revision: 1684215

URL: http://svn.apache.org/r1684215
Log:
[GERONIMO-6543] Aries/Geronimo XA transaction recovery not working for heuristically completed
transactions

Modified:
    geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java

Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java
URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java?rev=1684215&r1=1684214&r2=1684215&view=diff
==============================================================================
--- geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java
(original)
+++ geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java
Mon Jun  8 16:10:49 2015
@@ -114,12 +114,7 @@ public class RecoveryImpl implements Rec
                 // This is a bit wasteful, but given our management of XAResources by "name",
is about the best we can do.
                 if (isNameInTransaction(xidNamesPair, name, xid)) {
                     log.trace("This xid was prepared from this XAResource: committing");
-                    try {
-                        xaResource.commit(xid, false);
-                    } catch(XAException e) {
-                        recoveryErrors.add(e);
-                        log.error("Recovery error", e);
-                    }
+                    commit(xaResource, xid);
                     removeNameFromTransaction(xidNamesPair, name, true);
                 } else {
                     log.trace("This xid was prepared from another XAResource, ignoring");
@@ -127,24 +122,14 @@ public class RecoveryImpl implements Rec
             } else if (txManager.getXidFactory().matchesGlobalId(xid.getGlobalTransactionId()))
{
                 //ours, but prepare not logged
                 log.trace("this xid was initiated from this tm but not prepared: rolling
back");
-                try {
-                    xaResource.rollback(xid);
-                } catch (XAException e) {
-                    recoveryErrors.add(e);
-                    log.error("Could not roll back", e);
-                }
+                rollback(xaResource, xid);
             } else if (txManager.getXidFactory().matchesBranchId(xid.getBranchQualifier()))
{
                 //our branch, but we did not start this tx.
                 TransactionImpl externalTx = externalGlobalIdMap.get(xid.getGlobalTransactionId());
                 if (externalTx == null) {
                     //we did not prepare this branch, rollback.
                     log.trace("this xid is from an external transaction and was not prepared:
rolling back");
-                    try {
-                        xaResource.rollback(xid);
-                    } catch (XAException e) {
-                        recoveryErrors.add(e);
-                        log.error("Could not roll back", e);
-                    }
+                    rollback(xaResource, xid);
                 } else {
                     log.trace("this xid is from an external transaction and was prepared
in this tm.  Waiting for instructions from transaction originator");
                     //we prepared this branch, must wait for commit/rollback command.
@@ -160,6 +145,48 @@ public class RecoveryImpl implements Rec
             }
         }
     }
+
+    private void commit(NamedXAResource xaResource, Xid xid) {
+        doCommitOrRollback(xaResource, xid, true);
+    }
+
+    private void rollback(NamedXAResource xaResource, Xid xid) {
+        doCommitOrRollback(xaResource, xid, false);
+    }
+
+    private void doCommitOrRollback(NamedXAResource xaResource, Xid xid, boolean commit)
{
+        try {
+            if (commit) {
+                xaResource.commit(xid, false);
+            } else {
+                xaResource.rollback(xid);
+            }
+        } catch (XAException e) {
+            try {
+                if (e.errorCode == XAException.XA_HEURRB) {
+                    log.info("Transaction has been heuristically rolled back");
+                    xaResource.forget(xid);
+                } else if (e.errorCode == XAException.XA_HEURMIX) {
+                    log.info("Transaction has been heuristically committed and rolled back");
+                    xaResource.forget(xid);
+                } else if (e.errorCode == XAException.XA_HEURCOM) {
+                    log.info("Transaction has been heuristically committed");
+                    xaResource.forget(xid);
+                } else {
+                    recoveryErrors.add(e);
+                    log.error("Could not roll back", e);
+                }
+            } catch (XAException e2) {
+                if (e2.errorCode == XAException.XAER_NOTA) {
+                    // NOTA in response to forget, means the resource already forgot the
transaction
+                    // ignore
+                } else {
+                    recoveryErrors.add(e);
+                    log.error("Could not roll back", e);
+                }
+            }
+        }
+    }
 
     private boolean isNameInTransaction(XidBranchesPair xidBranchesPair, String name, Xid
xid) {
         for (TransactionBranchInfo transactionBranchInfo : xidBranchesPair.getBranches())
{



Mime
View raw message