geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lin...@apache.org
Subject svn commit: r727489 - in /geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager: RecoveryImpl.java TransactionImpl.java TransactionManagerImpl.java
Date Wed, 17 Dec 2008 19:41:20 GMT
Author: linsun
Date: Wed Dec 17 11:41:20 2008
New Revision: 727489

URL: http://svn.apache.org/viewvc?rev=727489&view=rev
Log:
merge rev 727474(GERONIMO-4471), rev 727065 (GERONIMO-4461 GERONIMO-4466) from branch 2.1

Modified:
    geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/RecoveryImpl.java
    geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
    geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.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=727489&r1=727488&r2=727489&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
Wed Dec 17 11:41:20 2008
@@ -28,6 +28,8 @@
 import java.util.HashSet;
 import java.util.Collection;
 
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
 import javax.transaction.SystemException;
 import javax.transaction.xa.XAException;
 import javax.transaction.xa.XAResource;
@@ -247,7 +249,7 @@
             resourceNames.remove(name);
         }
 
-        public void preparedCommit() throws SystemException {
+        public void preparedCommit() throws HeuristicRollbackException, HeuristicMixedException,
SystemException {
             if (!resourceNames.isEmpty()) {
                 throw new SystemException("This tx does not have all resource managers online,
commit not allowed yet");
             }

Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java?rev=727489&r1=727488&r2=727489&view=diff
==============================================================================
--- geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
(original)
+++ geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
Wed Dec 17 11:41:20 2008
@@ -265,7 +265,7 @@
             }
 
             if (status == Status.STATUS_MARKED_ROLLBACK) {
-                rollbackResources(resourceManagers);
+                rollbackResourcesDuringCommit(resourceManagers, false);
                 if (timedout) {
                     throw new RollbackException("Transaction timeout");
                 } else {
@@ -309,7 +309,20 @@
                     synchronized (this) {
                         status = Status.STATUS_ROLLEDBACK;
                     }
-                    throw (RollbackException) new RollbackException("Error during one-phase
commit").initCause(e);
+                    
+                    if (e.errorCode == XAException.XA_HEURRB) {
+                        manager.getCommitter().forget(manager.getBranchId());
+                        throw (HeuristicRollbackException) new HeuristicRollbackException("Error
during one-phase commit").initCause(e);
+                    } else if (e.errorCode == XAException.XA_HEURMIX) {
+                        manager.getCommitter().forget(manager.getBranchId());
+                        throw (HeuristicMixedException) new HeuristicMixedException("Error
during one-phase commit").initCause(e);
+                    } else if (e.errorCode == XAException.XA_HEURCOM) {
+                        // let's not throw an exception as the transaction has been committed
+                        log.info("Transaction has been heuristically committed");
+                        manager.getCommitter().forget(manager.getBranchId());
+                    } else {
+                        throw (RollbackException) new RollbackException("Error during one-phase
commit").initCause(e);
+                    }                    
                 }
             }
 
@@ -320,9 +333,12 @@
             if (willCommit) {
                 commitResources(resourceManagers);
             } else {
-                rollbackResources(resourceManagers);
-                throw new RollbackException("Unable to commit");
+                // set everRollback to true here because the rollback here is caused by 
+                // XAException during the above internalPrepare
+                rollbackResourcesDuringCommit(resourceManagers, true);
             }
+        } catch (XAException e) {
+           throw (SystemException) new SystemException("Error during commit").initCause(e);
         } finally {
             afterCompletion();
             synchronized (this) {
@@ -375,7 +391,7 @@
     }
 
     //used from XATerminator for commit phase of non-readonly remotely controlled tx.
-    void preparedCommit() throws SystemException {
+    void preparedCommit() throws HeuristicRollbackException, HeuristicMixedException, SystemException
{
         try {
             commitResources(resourceManagers);
         } finally {
@@ -423,8 +439,13 @@
             } catch (XAException e) {
                 synchronized (this) {
                     status = Status.STATUS_MARKED_ROLLBACK;
-                    //TODO document why this is true from the spec.
-                    //XAException during prepare means we can assume resource is rolled back.
+                    /* Per JTA spec,  If the resource manager wants to roll back the transaction,

+                    it should do so by throwing an appropriate XAException in the prepare
method.
+                    Also per OTS spec:
+                    The resource can return VoteRollback under any circumstances, including
not having 
+                    any knowledge about the transaction (which might happen after a crash).
If this 
+                    response is returned, the transaction must be rolled back. Furthermore,
the Transaction 
+                    Service is not required to perform any additional operations on this
resource.*/
                     rms.remove();
                     break;
                 }
@@ -586,6 +607,7 @@
                 }
             }
         }
+
         synchronized (this) {
             status = Status.STATUS_ROLLEDBACK;
         }
@@ -594,21 +616,96 @@
         }
     }
 
-    private void commitResources(List rms) throws SystemException {
-        SystemException cause = null;
+    private void rollbackResourcesDuringCommit(List rms, boolean everRb) throws HeuristicMixedException,
RollbackException, SystemException {
+        XAException cause = null;
+        boolean everRolledback = everRb;
+        synchronized (this) {
+            status = Status.STATUS_ROLLING_BACK;
+        }
+        try {
+            for (Iterator i = rms.iterator(); i.hasNext();) {
+                TransactionBranch manager = (TransactionBranch) i.next();
+                try {
+                    manager.getCommitter().rollback(manager.getBranchId());
+                    everRolledback = true;
+                } catch (XAException e) {
+                    if (e.errorCode == XAException.XA_HEURRB) {
+                        // let's not set the cause here
+                        log.error("Transaction has been heuristically rolled back " + manager.getCommitter()
+ "; continuing with rollback", e);
+                        everRolledback = true;
+                        manager.getCommitter().forget(manager.getBranchId());
+                    } else if (e.errorCode == XAException.XA_HEURMIX) {
+                        log.error("Transaction has been heuristically committed and rolled
back " + manager.getCommitter() + "; continuing with rollback", e);
+                        cause = e;
+                        everRolledback = true;
+                        manager.getCommitter().forget(manager.getBranchId());
+                    } else if (e.errorCode == XAException.XA_HEURCOM) {
+                        log.error("Transaction has been heuristically committed " + manager.getCommitter()
+ "; continuing with rollback", e);
+                        cause = e;
+                        manager.getCommitter().forget(manager.getBranchId());
+                    } else if (cause == null) {
+                        cause = e;
+                    }
+                }
+            }
+        } catch (XAException e) {
+            throw (SystemException) new SystemException("Error during rolling back").initCause(e);
           
+        }
+        
+        synchronized (this) {
+            status = Status.STATUS_ROLLEDBACK;
+        }
+        
+        if (cause == null) {
+            throw (RollbackException) new RollbackException("Error during two phase commit").initCause(cause);
+        } else {
+            if (cause.errorCode == XAException.XA_HEURCOM && everRolledback) {
+                throw (HeuristicMixedException) new HeuristicMixedException("Error during
two phase commit").initCause(cause);
+            } else if (cause.errorCode == XAException.XA_HEURMIX) {
+                throw (HeuristicMixedException) new HeuristicMixedException("Error during
two phase commit").initCause(cause);
+            } else {            
+                throw (SystemException) new SystemException("Error during two phase commit").initCause(cause);
+            } 
+        }
+    }
+    
+    
+    private void commitResources(List rms) throws HeuristicRollbackException, HeuristicMixedException,
SystemException {
+        XAException cause = null;
+        boolean evercommit = false;
         synchronized (this) {
             status = Status.STATUS_COMMITTING;
         }
-        for (Iterator i = rms.iterator(); i.hasNext();) {
-            TransactionBranch manager = (TransactionBranch) i.next();
-            try {
-                manager.getCommitter().commit(manager.getBranchId(), false);
-            } catch (XAException e) {
-                log.error("Unexpected exception committing" + manager.getCommitter() + ";
continuing to commit other RMs", e);
-                if (cause == null) {
-                    cause = new SystemException(e.errorCode);
+        try {
+            for (Iterator i = rms.iterator(); i.hasNext();) {
+                TransactionBranch manager = (TransactionBranch) i.next();
+                try {
+                    manager.getCommitter().commit(manager.getBranchId(), false);
+                    evercommit = true;
+                } catch (XAException e) {
+                    log.error("Unexpected exception committing " + manager.getCommitter()
+ "; continuing to commit other RMs", e);
+                    
+                    if (e.errorCode == XAException.XA_HEURRB) {
+                        log.info("Transaction has been heuristically rolled back");
+                        cause = e;
+                        manager.getCommitter().forget(manager.getBranchId());
+                    } else if (e.errorCode == XAException.XA_HEURMIX) {
+                        log.info("Transaction has been heuristically committed and rolled
back");
+                        cause = e;
+                        evercommit = true;
+                        manager.getCommitter().forget(manager.getBranchId());
+                    } else if (e.errorCode == XAException.XA_HEURCOM) {
+                        // let's not throw an exception as the transaction has been committed
+                        log.info("Transaction has been heuristically committed");
+                        evercommit = true;
+                        manager.getCommitter().forget(manager.getBranchId());
+                    } else {
+                        cause = e;
+                    }
                 }
             }
+        } catch (XAException e) {
+            throw (SystemException) new SystemException("Error during two phase commit").initCause(e);
         }
         //if all resources were read only, we didn't write a prepare record.
         if (!rms.isEmpty()) {
@@ -623,7 +720,17 @@
             status = Status.STATUS_COMMITTED;
         }
         if (cause != null) {
-            throw cause;
+            if (cause.errorCode == XAException.XA_HEURRB && !evercommit) {
+                throw (HeuristicRollbackException) new HeuristicRollbackException("Error
during two phase commit").initCause(cause);
+            } else if (cause.errorCode == XAException.XA_HEURRB && evercommit) {
+                throw (HeuristicMixedException) new HeuristicMixedException("Error during
two phase commit").initCause(cause);
+            } else if (cause.errorCode == XAException.XA_HEURMIX) {
+                throw (HeuristicMixedException) new HeuristicMixedException("Error during
two phase commit").initCause(cause);
+            } else if (cause.errorCode == XAException.XA_HEURCOM) {
+                // ignore don't need to inform the tx originator
+            } else {
+                throw (SystemException) new SystemException("Error during two phase commit").initCause(cause);
+            } 
         }
     }
 

Modified: geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
URL: http://svn.apache.org/viewvc/geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java?rev=727489&r1=727488&r2=727489&view=diff
==============================================================================
--- geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
(original)
+++ geronimo/components/txmanager/trunk/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
Wed Dec 17 11:41:20 2008
@@ -294,6 +294,10 @@
         } else {
             try {
                 ((TransactionImpl) tx).preparedCommit();
+            } catch (HeuristicMixedException e) {
+                throw (XAException) new XAException().initCause(e);
+            } catch (HeuristicRollbackException e) {
+                throw (XAException) new XAException().initCause(e);
             } catch (SystemException e) {
                 throw (XAException) new XAException().initCause(e);
             }



Mime
View raw message