You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2006/09/12 01:12:00 UTC

svn commit: r442384 - in /geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager: Closeable.java TransactionImpl.java TransactionManagerImpl.java

Author: djencks
Date: Mon Sep 11 16:11:59 2006
New Revision: 442384

URL: http://svn.apache.org/viewvc?view=rev&rev=442384
Log:
GERONIMO-2349 jta 1.1 support methods in jta 1.0.1B tx manager, with extension jars for jta 1.1 support

Added:
    geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java   (with props)
Modified:
    geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
    geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java

Added: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java?view=auto&rev=442384
==============================================================================
--- geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java (added)
+++ geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java Mon Sep 11 16:11:59 2006
@@ -0,0 +1,27 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.transaction.manager;
+
+/**
+ * @version $Rev:$ $Date:$
+ */
+public interface Closeable {
+
+    void close();
+
+}

Propchange: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java?view=diff&rev=442384&r1=442383&r2=442384
==============================================================================
--- geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java (original)
+++ geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java Mon Sep 11 16:11:59 2006
@@ -18,12 +18,14 @@
 package org.apache.geronimo.transaction.manager;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+
 import javax.transaction.HeuristicMixedException;
 import javax.transaction.HeuristicRollbackException;
 import javax.transaction.RollbackException;
@@ -34,6 +36,7 @@
 import javax.transaction.xa.XAException;
 import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
+import javax.ejb.EJBException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -57,6 +60,10 @@
     private int status = Status.STATUS_NO_TRANSACTION;
     private Object logMark;
 
+    private final Map resources = new HashMap();
+    private Synchronization interposedSynchronization;
+    private final Map entityManagers = new HashMap();
+
     TransactionImpl(XidFactory xidFactory, TransactionLog txnLog, long transactionTimeoutMilliseconds) throws SystemException {
         this(xidFactory.createXid(), xidFactory, txnLog, transactionTimeoutMilliseconds);
     }
@@ -87,11 +94,38 @@
         this.timeout = Long.MAX_VALUE;
     }
 
-    public synchronized int getStatus() throws SystemException {
+    public synchronized int getStatus() {
         return status;
     }
 
-    public synchronized void setRollbackOnly() throws IllegalStateException, SystemException {
+    public Object getResource(Object key) {
+        return resources.get(key);
+    }
+
+    public boolean getRollbackOnly() {
+        return status == Status.STATUS_MARKED_ROLLBACK;
+    }
+
+    public Object getTransactionKey() {
+        return xid;
+    }
+
+    public int getTransactionStatus() {
+        return status;
+    }
+
+    public void putResource(Object key, Object value) {
+        if (key == null) {
+            throw new NullPointerException("You must supply a non-null key for putResource");
+        }
+        resources.put(key, value);
+    }
+
+    public void registerInterposedSynchronization(Synchronization synchronization) {
+        interposedSynchronization = synchronization;
+    }
+
+    public synchronized void setRollbackOnly() throws IllegalStateException {
         switch (status) {
             case Status.STATUS_ACTIVE:
             case Status.STATUS_PREPARING:
@@ -171,7 +205,7 @@
             //we know nothing about this XAResource or resource manager
             Xid branchId = xidFactory.createBranch(xid, resourceManagers.size() + 1);
             xaRes.start(branchId, XAResource.TMNOFLAGS);
-            activeXaResources.put(xaRes, addBranchXid(xaRes,  branchId));
+            activeXaResources.put(xaRes, addBranchXid(xaRes, branchId));
             return true;
         } catch (XAException e) {
             log.warn("Unable to enlist XAResource " + xaRes + ", errorCode: " + e.errorCode, e);
@@ -222,23 +256,19 @@
         beforePrepare();
 
         try {
-                      boolean timedout = false;
-                      if (TransactionTimer.getCurrentTime() > timeout)
-                      {
-                          status = Status.STATUS_MARKED_ROLLBACK;
-                          timedout = true;
-                      }
+            boolean timedout = false;
+            if (TransactionTimer.getCurrentTime() > timeout) {
+                status = Status.STATUS_MARKED_ROLLBACK;
+                timedout = true;
+            }
 
             if (status == Status.STATUS_MARKED_ROLLBACK) {
                 rollbackResources(resourceManagers);
-                              if(timedout)
-                              {
-                                  throw new RollbackException("Transaction timout");
-                              }
-                              else
-                              {
-                                  throw new RollbackException("Unable to commit: transaction marked for rollback");
-                              }
+                if (timedout) {
+                    throw new RollbackException("Transaction timout");
+                } else {
+                    throw new RollbackException("Unable to commit: transaction marked for rollback");
+                }
             }
             synchronized (this) {
                 if (status == Status.STATUS_ACTIVE) {
@@ -256,7 +286,6 @@
                 // resourceManagers is now immutable
             }
 
-
             // no-phase
             if (resourceManagers.size() == 0) {
                 synchronized (this) {
@@ -400,7 +429,6 @@
             }
         }
 
-
         // decision time...
         boolean willCommit;
         synchronized (this) {
@@ -471,9 +499,17 @@
             Synchronization synch;
             synchronized (this) {
                 if (i == syncList.size()) {
+                    if (interposedSynchronization != null) {
+                        synch = interposedSynchronization;
+                        i++;
+                    } else {
+                        return;
+                    }
+                } else if (i == syncList.size() + 1) {
                     return;
+                } else {
+                    synch = (Synchronization) syncList.get(i++);
                 }
-                synch = (Synchronization) syncList.get(i++);
             }
             try {
                 synch.beforeCompletion();
@@ -488,6 +524,13 @@
 
     private void afterCompletion() {
         // this does not synchronize because nothing can modify our state at this time
+        if (interposedSynchronization != null) {
+            try {
+                interposedSynchronization.afterCompletion(status);
+            } catch (Exception e) {
+                log.warn("Unexpected exception from afterCompletion; continuing", e);
+            }
+        }
         for (Iterator i = syncList.iterator(); i.hasNext();) {
             Synchronization synch = (Synchronization) i.next();
             try {
@@ -497,6 +540,10 @@
                 continue;
             }
         }
+        for (Iterator i = entityManagers.values().iterator(); i.hasNext();) {
+            Closeable entityManager = (Closeable) i.next();
+            entityManager.close();
+        }
     }
 
     private void endResources() {
@@ -579,7 +626,7 @@
                 txnLog.commit(xid, logMark);
             } catch (LogException e) {
                 log.error("Unexpected exception logging commit completion for xid " + xid, e);
-                throw (SystemException)new SystemException("Unexpected error logging commit completion for xid " + xid).initCause(e);
+                throw (SystemException) new SystemException("Unexpected error logging commit completion for xid " + xid).initCause(e);
             }
         }
         synchronized (this) {
@@ -634,6 +681,17 @@
         return manager;
     }
 
+    public Object getEntityManager(String persistenceUnit) {
+        return entityManagers.get(persistenceUnit);
+    }
+
+    public void setEntityManager(String persistenceUnit, Object entityManager) {
+        Object oldEntityManager = entityManagers.put(persistenceUnit, entityManager);
+        if (oldEntityManager != null) {
+            throw new EJBException("EntityManager " + oldEntityManager + " for persistenceUnit " + persistenceUnit + " already associated with this transaction " + xid);
+        }
+    }
+
     private static class TransactionBranch implements TransactionBranchInfo {
         private final XAResource committer;
         private final Xid branchId;
@@ -653,7 +711,7 @@
 
         public String getResourceName() {
             if (committer instanceof NamedXAResource) {
-            return ((NamedXAResource)committer).getName();
+                return ((NamedXAResource) committer).getName();
             } else {
                 throw new IllegalStateException("Cannot log transactions unles XAResources are named! " + committer);
             }

Modified: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java?view=diff&rev=442384&r1=442383&r2=442384
==============================================================================
--- geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java (original)
+++ geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java Mon Sep 11 16:11:59 2006
@@ -23,12 +23,14 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+
 import javax.transaction.HeuristicMixedException;
 import javax.transaction.HeuristicRollbackException;
 import javax.transaction.InvalidTransactionException;
 import javax.transaction.NotSupportedException;
 import javax.transaction.RollbackException;
 import javax.transaction.Status;
+import javax.transaction.Synchronization;
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
@@ -121,7 +123,7 @@
         return new ArrayList(resourceManagers);
     }
 
-    public Transaction getTransaction() throws SystemException {
+    public Transaction getTransaction() {
         return (Transaction) threadTx.get();
     }
 
@@ -136,7 +138,7 @@
         fireThreadAssociated(tx);
     }
 
-    private void unassociate() throws SystemException {
+    private void unassociate() {
         Transaction tx = getTransaction();
         if (tx != null) {
             associatedTransactions.remove(tx);
@@ -200,8 +202,53 @@
         associate((TransactionImpl) tx);
     }
 
-    public void setRollbackOnly() throws IllegalStateException, SystemException {
-        Transaction tx = getTransaction();
+    public Object getResource(Object key) {
+        TransactionImpl tx = getActiveTransactionImpl();
+        return tx.getResource(key);
+    }
+
+    private TransactionImpl getActiveTransactionImpl() {
+        TransactionImpl tx = (TransactionImpl)threadTx.get();
+        if (tx == null) {
+            throw new IllegalStateException("No tx on thread");
+        }
+        if (tx.getStatus() != Status.STATUS_ACTIVE) {
+            throw new IllegalStateException("Transaction " + tx + " is not active");
+        }
+        return tx;
+    }
+
+    public boolean getRollbackOnly() {
+        TransactionImpl tx = getActiveTransactionImpl();
+        return tx.getRollbackOnly();
+    }
+
+    public Object getTransactionKey() {
+        TransactionImpl tx = getActiveTransactionImpl();
+        return tx.getTransactionKey();
+    }
+
+    public int getTransactionStatus() {
+        TransactionImpl tx = getActiveTransactionImpl();
+        return tx.getTransactionStatus();
+    }
+
+    public void putResource(Object key, Object value) {
+        TransactionImpl tx = getActiveTransactionImpl();
+        tx.putResource(key, value);
+    }
+
+    /**
+     * jta 1.1 method so the jpa implementations can be told to flush their caches.
+     * @param synchronization
+     */
+    public void registerInterposedSynchronization(Synchronization synchronization) {
+        TransactionImpl tx = getActiveTransactionImpl();
+        tx.registerInterposedSynchronization(synchronization);
+    }
+
+    public void setRollbackOnly() throws IllegalStateException {
+        TransactionImpl tx = (TransactionImpl) threadTx.get();
         if (tx == null) {
             throw new IllegalStateException("No transaction associated with current thread");
         }
@@ -301,7 +348,7 @@
     }
 
     protected void recoverResourceManager(ResourceManager resourceManager) {
-        NamedXAResource namedXAResource = null;
+        NamedXAResource namedXAResource;
         try {
             namedXAResource = resourceManager.getRecoveryXAResources();
         } catch (SystemException e) {