geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject svn commit: r155376 - in geronimo/trunk/modules: connector/src/java/org/apache/geronimo/connector/outbound/ connector/src/test/org/apache/geronimo/connector/outbound/ timer/src/java/org/apache/geronimo/timer/ timer/src/test/org/apache/geronimo/timer/ transaction/src/java/org/apache/geronimo/transaction/ transaction/src/java/org/apache/geronimo/transaction/context/
Date Fri, 25 Feb 2005 23:10:29 GMT
Author: dain
Date: Fri Feb 25 15:10:24 2005
New Revision: 155376

URL: http://svn.apache.org/viewcvs?view=rev&rev=155376
Log:
Fixed bugs in TransactionContext and handling of the contexts unturned by turning back on
in-tx caching
Added support for entrancy tracking and killing InstanceContexts

Modified:
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java
    geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionCachingInterceptorTest.java
    geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/NontransactionalExecutorTask.java
    geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java
    geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/TransactionalExecutorTask.java
    geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java
    geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/DefaultInstanceContext.java
    geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/InstanceContext.java
    geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/InheritableTransactionContext.java
    geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java
    geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/UnspecifiedTransactionContext.java

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
Fri Feb 25 15:10:24 2005
@@ -27,6 +27,7 @@
 import org.apache.geronimo.transaction.ConnectionReleaser;
 import org.apache.geronimo.transaction.context.TransactionContext;
 import org.apache.geronimo.transaction.context.TransactionContextManager;
+import org.apache.geronimo.transaction.context.InheritableTransactionContext;
 
 /**
  * TransactionCachingInterceptor.java
@@ -59,16 +60,15 @@
     }
 
     public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
-        TransactionContext transactionContext = transactionContextManager.getContext();
         //There can be an inactive transaction context when a connection is requested in
         //Synchronization.afterCompletion().
-        if (transactionContext == null || !transactionContext.isActive()) {
-            next.getConnection(connectionInfo);
-        } else {
-            ManagedConnectionInfos managedConnectionInfos = (ManagedConnectionInfos) transactionContext.getManagedConnectionInfo(this);
+        TransactionContext transactionContext = transactionContextManager.getContext();
+        if ((transactionContext instanceof InheritableTransactionContext) && ((InheritableTransactionContext)
transactionContext).isActive()) {
+            InheritableTransactionContext inheritableTransactionContext = ((InheritableTransactionContext)
transactionContext);
+            ManagedConnectionInfos managedConnectionInfos = (ManagedConnectionInfos) inheritableTransactionContext.getManagedConnectionInfo(this);
             if (managedConnectionInfos == null) {
                 managedConnectionInfos = new ManagedConnectionInfos();
-                transactionContext.setManagedConnectionInfo(this, managedConnectionInfos);
+                inheritableTransactionContext.setManagedConnectionInfo(this, managedConnectionInfos);
             }
             if (connectionInfo.isUnshareable()) {
                 if (!managedConnectionInfos.containsUnshared(connectionInfo.getManagedConnectionInfo()))
{
@@ -85,6 +85,8 @@
                     managedConnectionInfos.setShared(connectionInfo.getManagedConnectionInfo());
                 }
             }
+        } else {
+            next.getConnection(connectionInfo);
         }
     }
 
@@ -96,7 +98,7 @@
         }
 
         TransactionContext transactionContext = transactionContextManager.getContext();
-        if (transactionContext != null && transactionContext.isActive()) {
+        if ((transactionContext instanceof InheritableTransactionContext) && ((InheritableTransactionContext)
transactionContext).isActive()) {
             return;
         }
         internalReturn(connectionInfo, connectionReturnAction);

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java
(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java
Fri Feb 25 15:10:24 2005
@@ -24,6 +24,7 @@
 
 import org.apache.geronimo.transaction.context.TransactionContext;
 import org.apache.geronimo.transaction.context.TransactionContextManager;
+import org.apache.geronimo.transaction.context.InheritableTransactionContext;
 
 /**
  * TransactionEnlistingInterceptor.java
@@ -48,9 +49,12 @@
         try {
             ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
             TransactionContext transactionContext = transactionContextManager.getContext();
-            if (transactionContext != null && transactionContext.isActive()) {
-                XAResource xares = mci.getXAResource();
-                transactionContext.getTransaction().enlistResource(xares);
+            if ((transactionContext instanceof InheritableTransactionContext)) {
+                InheritableTransactionContext inheritableTransactionContext = ((InheritableTransactionContext)
transactionContext);
+                if (inheritableTransactionContext.isActive()) {
+                    XAResource xares = mci.getXAResource();
+                    inheritableTransactionContext.getTransaction().enlistResource(xares);
+                }
             }
 
         } catch (SystemException e) {
@@ -76,9 +80,12 @@
         try {
             ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
             TransactionContext transactionContext = transactionContextManager.getContext();
-            if (transactionContext != null && transactionContext.isActive()) {
-                XAResource xares = mci.getXAResource();
-                transactionContext.getTransaction().delistResource(xares, XAResource.TMSUSPEND);
+            if ((transactionContext instanceof InheritableTransactionContext)) {
+                InheritableTransactionContext inheritableTransactionContext = ((InheritableTransactionContext)
transactionContext);
+                if (inheritableTransactionContext.isActive()) {
+                    XAResource xares = mci.getXAResource();
+                    inheritableTransactionContext.getTransaction().delistResource(xares,
XAResource.TMSUSPEND);
+                }
             }
 
         } catch (SystemException e) {

Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionCachingInterceptorTest.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionCachingInterceptorTest.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionCachingInterceptorTest.java
(original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionCachingInterceptorTest.java
Fri Feb 25 15:10:24 2005
@@ -127,8 +127,6 @@
         transactionCachingInterceptor.getConnection(connectionInfo1);
         assertTrue("Expected to get an initial connection", obtainedConnectionInfo != null);
         assertTrue("Expected nothing returned yet", returnedConnectionInfo == null);
-        assertTrue("Expected no ManagedConnectionInfo in the TransactionContext",
-                null == transactionContextManager.getContext().getManagedConnectionInfo(transactionCachingInterceptor));
         obtainedConnectionInfo = null;
         ConnectionInfo connectionInfo2 = makeConnectionInfo();
         transactionCachingInterceptor.getConnection(connectionInfo2);
@@ -136,18 +134,12 @@
         assertTrue("Expected nothing returned yet", returnedConnectionInfo == null);
         assertTrue("Expected different ManagedConnectionInfo in both ConnectionInfos",
                 connectionInfo1.getManagedConnectionInfo() != connectionInfo2.getManagedConnectionInfo());
-        assertTrue("Expected no ManagedConnectionInfo in the TransactionContext",
-                null == transactionContextManager.getContext().getManagedConnectionInfo(transactionCachingInterceptor));
         //we didn't create any handles, so the "ManagedConnection" should be returned.
-        assertTrue("Expected TransactionContext to report inactive", !transactionContextManager.getContext().isActive());
         transactionCachingInterceptor.returnConnection(connectionInfo1, ConnectionReturnAction.RETURN_HANDLE);
         assertTrue("Expected connection to be returned", returnedConnectionInfo != null);
         returnedConnectionInfo = null;
         transactionCachingInterceptor.returnConnection(connectionInfo2, ConnectionReturnAction.RETURN_HANDLE);
         assertTrue("Expected connection to be returned", returnedConnectionInfo != null);
-
-        assertTrue("Expected TransactionContext to report inactive", !transactionContextManager.getContext().isActive());
-
     }
 
     public void testTransactionIndependence() throws Exception {

Modified: geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/NontransactionalExecutorTask.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/NontransactionalExecutorTask.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/NontransactionalExecutorTask.java
(original)
+++ geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/NontransactionalExecutorTask.java
Fri Feb 25 15:10:24 2005
@@ -19,14 +19,12 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.geronimo.timer.ExecutorTask;
+import org.apache.geronimo.transaction.context.TransactionContext;
+import org.apache.geronimo.transaction.context.UnspecifiedTransactionContext;
 
 /**
- *
- *
  * @version $Rev$ $Date$
- *
- * */
+ */
 public class NontransactionalExecutorTask implements ExecutorTask {
 
     private static final Log log = LogFactory.getLog(NontransactionalExecutorTask.class);
@@ -42,18 +40,26 @@
     }
 
     public void run() {
+        UnspecifiedTransactionContext transactionContext = new UnspecifiedTransactionContext();
+        TransactionContext oldTransactionContext = TransactionContext.getContext();
+        TransactionContext.setContext(transactionContext);
         try {
-            userTask.run();
-        } catch (Exception e) {
-            log.info(e);
-        }
-        try {
-            threadPooledTimer.workPerformed(workInfo);
-        } catch (PersistenceException e) {
-            log.info(e);
-        }
-        if (workInfo.isOneTime()) {
-            threadPooledTimer.removeWorkInfo(workInfo);
+            try {
+                userTask.run();
+            } catch (Exception e) {
+                log.info(e);
+            }
+            try {
+                threadPooledTimer.workPerformed(workInfo);
+            } catch (PersistenceException e) {
+                log.info(e);
+            }
+            if (workInfo.isOneTime()) {
+                threadPooledTimer.removeWorkInfo(workInfo);
+            }
+        } finally {
+            transactionContext.commit();
+            TransactionContext.setContext(oldTransactionContext);
         }
     }
 

Modified: geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java
(original)
+++ geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java
Fri Feb 25 15:10:24 2005
@@ -37,6 +37,7 @@
 import org.apache.geronimo.gbean.GBeanLifecycle;
 import org.apache.geronimo.transaction.context.TransactionContext;
 import org.apache.geronimo.transaction.context.TransactionContextManager;
+import org.apache.geronimo.transaction.context.InheritableTransactionContext;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -243,13 +244,21 @@
 
     void registerSynchronization(Synchronization sync) throws RollbackException, SystemException
{
         TransactionContext transactionContext = transactionContextManager.getContext();
+
         //TODO move the registerSynchronization to the TransactionContext
-        Transaction transaction = transactionContext == null? null: transactionContext.getTransaction();
+        Transaction transaction;
+        if (transactionContext instanceof InheritableTransactionContext) {
+            InheritableTransactionContext inheritableTransactionContext = ((InheritableTransactionContext)
transactionContext);
+            transaction = inheritableTransactionContext.getTransaction();
+            assert transaction == null || inheritableTransactionContext.isActive(): "Trying
to register a sync on an inactive transaction context";
+        } else {
+            transaction = null;
+        }
+
         if (transaction == null) {
             sync.beforeCompletion();
             sync.afterCompletion(Status.STATUS_COMMITTED);
         } else {
-            assert transactionContext.isActive(): "Trying to register a sync on an inactive
transaction context";
             transaction.registerSynchronization(sync);
         }
     }

Modified: geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/TransactionalExecutorTask.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/TransactionalExecutorTask.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/TransactionalExecutorTask.java
(original)
+++ geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/TransactionalExecutorTask.java
Fri Feb 25 15:10:24 2005
@@ -17,26 +17,14 @@
 
 package org.apache.geronimo.timer;
 
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.geronimo.transaction.context.ContainerTransactionContext;
 import org.apache.geronimo.transaction.context.TransactionContextManager;
-import org.apache.geronimo.timer.ExecutorTask;
-import org.apache.geronimo.timer.PersistenceException;
-import org.apache.geronimo.timer.ThreadPooledTimer;
 
 /**
- *
- *
  * @version $Rev$ $Date$
- *
- * */
+ */
 public class TransactionalExecutorTask implements ExecutorTask {
     private static final Log log = LogFactory.getLog(TransactionalExecutorTask.class);
 
@@ -54,49 +42,38 @@
         this.transactionContextManager = transactionContextManager;
         this.repeatCount = repeatCount;
     }
-
+    
     public void run() {
         ContainerTransactionContext transactionContext = null;
         for (int tries = 0; tries < repeatCount; tries++) {
             try {
                 transactionContext = transactionContextManager.newContainerTransactionContext();
-            } catch (NotSupportedException e) {
-                log.info(e);
-                break;
-            } catch (SystemException e) {
-                log.info(e);
+            } catch (Exception e) {
+                log.info("Exception occured while starting container transaction", e);
                 break;
             }
             try {
                 try {
                     userTask.run();
                 } catch (Exception e) {
-                    log.info(e);
+                    log.info("Exception occured while running user task", e);
                 }
                 try {
                     threadPooledTimer.workPerformed(workInfo);
                 } catch (PersistenceException e) {
-                    log.info(e);
+                    log.info("Exception occured while updating timer persistent state", e);
                 }
             } finally {
                 try {
-                    if (transactionContext.getRollbackOnly()) {
-                        transactionContext.rollback();
-                    } else {
-                        transactionContext.commit();
+                    if (transactionContext.commit()) {
                         if (workInfo.isOneTime()) {
                             threadPooledTimer.removeWorkInfo(workInfo);
                         }
+                        // todo this is a very weird code structure.... returning from a
finally is very confusing
                         return;
                     }
-                } catch (SystemException e) {
-                    log.info(e);
-                } catch (HeuristicMixedException e) {
-                    log.info(e);
-                } catch (HeuristicRollbackException e) {
-                    log.info(e);
-                } catch (RollbackException e) {
-                    log.info(e);
+                } catch (Exception e) {
+                    log.info("Exception occured while completing container transaction",
e);
                 }
             }
         }

Modified: geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java
(original)
+++ geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java
Fri Feb 25 15:10:24 2005
@@ -23,11 +23,6 @@
 import org.apache.geronimo.transaction.context.TransactionContext;
 import org.apache.geronimo.transaction.context.TransactionContextManager;
 import org.apache.geronimo.timer.vm.VMWorkerPersistence;
-import org.apache.geronimo.timer.ExecutorTaskFactory;
-import org.apache.geronimo.timer.ThreadPooledTimer;
-import org.apache.geronimo.timer.UserTaskFactory;
-import org.apache.geronimo.timer.WorkerPersistence;
-import org.apache.geronimo.timer.WorkInfo;
 
 /**
  *
@@ -73,7 +68,7 @@
         for (long i = 0; i < COUNT; i++) {
             timer.schedule(userTaskFactory, key, userId, userKey, i);
         }
-        Thread.currentThread().sleep(COUNT + SLOP);
+        Thread.sleep(COUNT + SLOP);
         assertEquals(COUNT, counter.get());
     }
 
@@ -85,7 +80,7 @@
         for (int i = 0; i < workInfos.length; i++) {
             workInfos[i].getExecutorFeedingTimerTask().cancel();
         }
-        Thread.currentThread().sleep(SLOP + DELAY);
+        Thread.sleep(SLOP + DELAY);
         assertEquals(0, counter.get());
     }
 
@@ -98,7 +93,7 @@
 
         timer.doStart();
         timer.playback(key, userTaskFactory);
-        Thread.currentThread().sleep(2 * SLOP + DELAY);
+        Thread.sleep(2 * SLOP + DELAY);
         assertEquals(COUNT, counter.get());
     }
 
@@ -134,48 +129,48 @@
         for (long i = 0; i < COUNT; i++) {
             timer.schedule(userTaskFactory, key, userId, userKey, i);
         }
-        Thread.currentThread().sleep(COUNT + SLOP);
+        Thread.sleep(COUNT + SLOP);
         assertEquals(0, counter.get());
         transactionContext.commit();
-        Thread.currentThread().sleep(COUNT + SLOP);
+        Thread.sleep(COUNT + SLOP);
         assertEquals(COUNT, counter.get());
     }
 
     public void testCancelInCommittedTransaction() throws Exception {
-        Thread.currentThread().sleep(SLOP + DELAY);
+        Thread.sleep(SLOP + DELAY);
         WorkInfo[] workInfos = new WorkInfo[COUNT];
         for (long i = 0; i < COUNT; i++) {
             workInfos[(int) i] = timer.scheduleAtFixedRate(key, userTaskFactory, userId,
userKey, DELAY, DELAY);
         }
-        Thread.currentThread().sleep(SLOP + DELAY);
+        Thread.sleep(SLOP + DELAY);
         assertEquals(COUNT, counter.get());
         TransactionContext transactionContext = transactionContextManager.newContainerTransactionContext();
         for (int i = 0; i < workInfos.length; i++) {
             workInfos[i].getExecutorFeedingTimerTask().cancel();
         }
-        Thread.currentThread().sleep(SLOP + DELAY);
+        Thread.sleep(SLOP + DELAY);
         assertEquals(COUNT, counter.get());
         transactionContext.commit();
-        Thread.currentThread().sleep(SLOP + DELAY);
+        Thread.sleep(SLOP + DELAY);
         assertEquals(COUNT, counter.get());
     }
 
     public void testCancelInRolledBackTransaction() throws Exception {
-        Thread.currentThread().sleep(SLOP + DELAY);
+        Thread.sleep(SLOP + DELAY);
         WorkInfo[] workInfos = new WorkInfo[COUNT];
         for (long i = 0; i < COUNT; i++) {
             workInfos[(int) i] = timer.scheduleAtFixedRate(key, userTaskFactory, userId,
userKey, DELAY, DELAY);
         }
-        Thread.currentThread().sleep(SLOP + DELAY);
+        Thread.sleep(SLOP + DELAY);
         assertEquals(COUNT, counter.get());
         TransactionContext transactionContext = transactionContextManager.newContainerTransactionContext();
         for (int i = 0; i < workInfos.length; i++) {
             workInfos[i].getExecutorFeedingTimerTask().cancel();
         }
-        Thread.currentThread().sleep(SLOP + DELAY);
+        Thread.sleep(SLOP + DELAY);
         assertEquals(COUNT, counter.get());
         transactionContext.rollback();
-        Thread.currentThread().sleep(SLOP + DELAY);
+        Thread.sleep(SLOP + DELAY);
         // Catches up with two periods.
         assertEquals(3 * COUNT, counter.get());
     }
@@ -183,13 +178,13 @@
     public void testRepeatCountFromPersisted() throws Exception {
         assert DELAY > 2 * SLOP;
         timer.scheduleAtFixedRate(key, userTaskFactory, userId, userKey, 0L, DELAY);
-        Thread.currentThread().sleep(4 * DELAY + SLOP);
+        Thread.sleep(4 * DELAY + SLOP);
         timer.doStop();
         assertEquals(5, counter.get());
 
         timer.doStart();
         timer.playback(key, userTaskFactory);
-        Thread.currentThread().sleep(5 * DELAY + SLOP);
+        Thread.sleep(5 * DELAY + SLOP);
         assertEquals(2 * 5, counter.get());
 
     }

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/DefaultInstanceContext.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/DefaultInstanceContext.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/DefaultInstanceContext.java
(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/DefaultInstanceContext.java
Fri Feb 25 15:10:24 2005
@@ -29,10 +29,11 @@
  *
  * */
 public class DefaultInstanceContext implements InstanceContext {
-
     private final Map connectionManagerMap = new HashMap();
     private final Set unshareableResources;
     private final Set applicationManagedSecurityResources;
+    private int callDepth;
+    private boolean dead = false;
 
     public DefaultInstanceContext(Set unshareableResources, Set applicationManagedSecurityResources)
{
         this.unshareableResources = unshareableResources;
@@ -43,9 +44,6 @@
         return null;
     }
 
-    public void setId(Object id) {
-    }
-
     public Object getContainerId() {
         return null;
     }
@@ -62,6 +60,9 @@
     public void afterCommit(boolean status) throws Exception {
     }
 
+    public void unassociate() throws Throwable {
+    }
+
     public Map getConnectionManagerMap() {
         return connectionManagerMap;
     }
@@ -74,4 +75,24 @@
         return applicationManagedSecurityResources;
     }
 
+    public boolean isInCall() {
+        return callDepth > 0;
+    }
+
+    public void enter() {
+        callDepth++;
+    }
+
+    public void exit() {
+        assert isInCall();
+        callDepth--;
+    }
+
+    public boolean isDead() {
+        return dead;
+    }
+
+    public void die() {
+        dead = true;
+    }
 }

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/InstanceContext.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/InstanceContext.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/InstanceContext.java
(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/InstanceContext.java
Fri Feb 25 15:10:24 2005
@@ -29,8 +29,6 @@
 public interface InstanceContext {
     Object getId();
 
-    void setId(Object id);
-
     Object getContainerId();
 
     void associate() throws Throwable;
@@ -41,6 +39,8 @@
 
     void afterCommit(boolean status) throws Throwable;
 
+    void unassociate() throws Throwable;
+
     /**
      * IMPORTANT INVARIANT: this should always return a map, never null.
      * @return map of ConnectionManager to (list of ) managed connection info objects.
@@ -51,4 +51,13 @@
 
     Set getApplicationManagedSecurityResources();
 
+    boolean isInCall();
+
+    void enter();
+
+    void exit();
+
+    boolean isDead();
+
+    void die();
 }

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/InheritableTransactionContext.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/InheritableTransactionContext.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/InheritableTransactionContext.java
(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/InheritableTransactionContext.java
Fri Feb 25 15:10:24 2005
@@ -17,6 +17,10 @@
 
 package org.apache.geronimo.transaction.context;
 
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
 import javax.transaction.SystemException;
 import javax.transaction.Status;
 import javax.transaction.Transaction;
@@ -27,16 +31,17 @@
 import javax.transaction.RollbackException;
 
 import org.apache.geronimo.transaction.ExtendedTransactionManager;
+import org.apache.geronimo.transaction.ConnectionReleaser;
+import org.apache.geronimo.transaction.InstanceContext;
 
 /**
- *
- *
  * @version $Rev$ $Date$
  */
 public abstract class InheritableTransactionContext extends TransactionContext {
     private final ExtendedTransactionManager txnManager;
     private Transaction transaction;
     private boolean threadAssociated = false;
+    private Map managedConnections;
 
     protected InheritableTransactionContext(ExtendedTransactionManager txnManager) {
         this.txnManager = txnManager;
@@ -55,9 +60,26 @@
         return transaction;
     }
 
+    public void setManagedConnectionInfo(ConnectionReleaser key, Object info) {
+        if (managedConnections == null) {
+            managedConnections = new HashMap();
+        }
+        managedConnections.put(key, info);
+    }
+
+    public Object getManagedConnectionInfo(ConnectionReleaser key) {
+        if (managedConnections == null) {
+            return null;
+        }
+        return managedConnections.get(key);
+    }
+
     public boolean isActive() {
+        if (transaction == null) {
+            return false;
+        }
         try {
-            int status = txnManager.getStatus();
+            int status = transaction.getStatus();
             return status == Status.STATUS_ACTIVE || status == Status.STATUS_MARKED_ROLLBACK;
         } catch (SystemException e) {
             return false;
@@ -65,7 +87,6 @@
     }
 
     public boolean getRollbackOnly() throws SystemException {
-        Transaction transaction = getTransaction();
         if (transaction == null) {
             throw new IllegalStateException("There is no transaction in progress.");
         }
@@ -77,7 +98,6 @@
     }
 
     public void setRollbackOnly() throws IllegalStateException, SystemException {
-        Transaction transaction = getTransaction();
         if (transaction == null) {
             throw new IllegalStateException("There is no transaction in progress.");
         }
@@ -85,13 +105,16 @@
     }
 
     public void begin(long transactionTimeoutMilliseconds) throws SystemException, NotSupportedException
{
+        assert transaction == null:  "Already associated with a transaction";
         transaction = txnManager.begin(transactionTimeoutMilliseconds);
         threadAssociated = true;
     }
 
     public void suspend() throws SystemException {
         Transaction suspendedTransaction = txnManager.suspend();
-        assert (transaction == suspendedTransaction) : "suspend did not return our transaction.
ours: " + transaction + ", suspended returned: " + suspendedTransaction;
+        if (transaction != suspendedTransaction) {
+            throw new SystemException("Suspend did not return our transaction: expectedTx="
+ transaction + ", suspendedTx=" + suspendedTransaction);
+        }
         threadAssociated = false;
     }
 
@@ -101,6 +124,29 @@
     }
 
     public boolean commit() throws HeuristicMixedException, HeuristicRollbackException, SystemException,
RollbackException {
+        return complete();
+    }
+
+    public void rollback() throws SystemException {
+        setRollbackOnly();
+        try {
+            complete();
+        } catch (SystemException e) {
+            throw e;
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Error e) {
+            throw e;
+        } catch (Exception e) {
+            throw (SystemException) new SystemException("After commit of container transaction
failed").initCause(e);
+        }
+    }
+
+    private boolean complete() throws HeuristicMixedException, HeuristicRollbackException,
SystemException, RollbackException {
+        if (transaction == null) {
+            throw new IllegalStateException("There is no transaction in progress.");
+        }
+
         boolean wasCommitted = false;
         try {
             if (isRolledback()) {
@@ -120,6 +166,14 @@
                 return false;
             }
 
+            // verify our tx is the current tx associated with the thread
+            // this is really only an error case and should never happen, but just to be
sure double check
+            // immedately before committing using the transaction manager
+            Transaction currentTransaction = txnManager.getTransaction();
+            if (currentTransaction != transaction) {
+                throw new SystemException("An unknown transaction is currently associated
with the thread: expectedTx=" + transaction + ", currentTx=" + currentTransaction);
+            }
+
             txnManager.commit();
             wasCommitted = true;
         } catch (Throwable t) {
@@ -130,23 +184,82 @@
             } catch (Throwable e) {
                 rollbackAndThrow("After commit of container transaction failed", e);
             } finally {
+                unassociateAll();
                 connectorAfterCommit();
                 transaction = null;
+                threadAssociated = false;
             }
         }
         return wasCommitted;
     }
 
+    private void beforeCommit() throws Throwable {
+        // @todo allow for enrollment during pre-commit
+        ArrayList toFlush = getAssociatedContexts();
+        for (Iterator i = toFlush.iterator(); i.hasNext();) {
+            InstanceContext context = (InstanceContext) i.next();
+            if (!context.isDead()) {
+                context.beforeCommit();
+            }
+        }
+    }
+
+    private void afterCommit(boolean status) throws Throwable {
+        Throwable firstThrowable = null;
+        ArrayList toFlush = getAssociatedContexts();
+        for (Iterator i = toFlush.iterator(); i.hasNext();) {
+            InstanceContext context = (InstanceContext) i.next();
+            if (!context.isDead()) {
+                try {
+                    context.afterCommit(status);
+                } catch (Throwable e) {
+                    if (firstThrowable == null) {
+                        firstThrowable = e;
+                    }
+                }
+            }
+        }
+
+        if (firstThrowable instanceof Error) {
+            throw (Error) firstThrowable;
+        } else if (firstThrowable instanceof Exception) {
+            throw (Exception) firstThrowable;
+        } else if (firstThrowable != null) {
+            throw (SystemException) new SystemException().initCause(firstThrowable);
+        }
+    }
+
+    private void connectorAfterCommit() {
+        if (managedConnections != null) {
+            for (Iterator entries = managedConnections.entrySet().iterator(); entries.hasNext();)
{
+                Map.Entry entry = (Map.Entry) entries.next();
+                ConnectionReleaser key = (ConnectionReleaser) entry.getKey();
+                key.afterCompletion(entry.getValue());
+            }
+            //If BeanTransactionContext never reuses the same instance for sequential BMT,
this
+            //clearing is unnecessary.
+            managedConnections.clear();
+        }
+    }
+
     private boolean isRolledback() throws SystemException {
         int status;
         try {
             status = transaction.getStatus();
         } catch (SystemException e) {
-            txnManager.rollback();
+            transaction.rollback();
             throw e;
         }
 
         if (status == Status.STATUS_MARKED_ROLLBACK) {
+            // verify our tx is the current tx associated with the thread
+            // this is really only an error case and should never happen, but just to be
sure double check
+            // immedately before committing using the transaction manager
+            Transaction currentTransaction = txnManager.getTransaction();
+            if (currentTransaction != transaction) {
+                throw new SystemException("An unknown transaction is currently associated
with the thread: expectedTx=" + transaction + ", currentTx=" + currentTransaction);
+            }
+
             // we need to rollback
             txnManager.rollback();
             return true;
@@ -160,7 +273,6 @@
 
     private void rollbackAndThrow(String message, Throwable throwable) throws HeuristicMixedException,
HeuristicRollbackException, SystemException, RollbackException {
         try {
-            // just incase there is a junk transaction on the thread
             if (txnManager.getStatus() != Status.STATUS_NO_TRANSACTION) {
                 txnManager.rollback();
             }
@@ -168,6 +280,18 @@
             log.error("Unable to roll back transaction", t);
         }
 
+        try {
+            // make doubly sure our transaction was rolled back
+            // this can happen when there was a junk transaction on the thread
+            int status = transaction.getStatus();
+            if (status != Status.STATUS_ROLLEDBACK &&
+                    status != Status.STATUS_ROLLING_BACK) {
+                transaction.rollback();
+            }
+        } catch (Throwable t) {
+            log.error("Unable to roll back transaction", t);
+        }
+
         if (throwable instanceof HeuristicMixedException) {
             throw (HeuristicMixedException) throwable;
         } else if (throwable instanceof HeuristicRollbackException) {
@@ -182,41 +306,6 @@
             throw (RuntimeException) throwable;
         } else {
             throw (SystemException) new SystemException(message).initCause(throwable);
-        }
-    }
-
-    public void rollback() throws SystemException {
-        try {
-            try {
-                if (txnManager.getStatus() != Status.STATUS_NO_TRANSACTION) {
-                    txnManager.rollback();
-                }
-            } finally {
-                try {
-                    afterCommit(false);
-                } catch (Throwable e) {
-                    try {
-                        // just incase there is a junk transaction on the thread
-                        if (txnManager.getStatus() != Status.STATUS_NO_TRANSACTION) {
-                            txnManager.rollback();
-                        }
-                    } catch (Throwable t1) {
-                        log.error("Unable to roll back transaction", t1);
-                    }
-
-                    if (e instanceof SystemException) {
-                        throw (SystemException) e;
-                    } else if (e instanceof Error) {
-                        throw (Error) e;
-                    } else if (e instanceof RuntimeException) {
-                        throw (RuntimeException) e;
-                    }
-                    throw (SystemException) new SystemException("After commit of container
transaction failed").initCause(e);
-                }
-            }
-        } finally {
-            connectorAfterCommit();
-            transaction = null;
         }
     }
 }

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java
(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java
Fri Feb 25 15:10:24 2005
@@ -18,27 +18,21 @@
 package org.apache.geronimo.transaction.context;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.Map;
 import javax.transaction.HeuristicMixedException;
 import javax.transaction.HeuristicRollbackException;
 import javax.transaction.InvalidTransactionException;
 import javax.transaction.RollbackException;
 import javax.transaction.SystemException;
-import javax.transaction.Transaction;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.geronimo.transaction.ConnectionReleaser;
 import org.apache.geronimo.transaction.DoubleKeyedHashMap;
 import org.apache.geronimo.transaction.InstanceContext;
 import org.tranql.cache.InTxCache;
 
 
 /**
- *
- *
  * @version $Rev$ $Date$
  */
 public abstract class TransactionContext {
@@ -56,9 +50,12 @@
     private InstanceContext currentContext;
     private final DoubleKeyedHashMap associatedContexts = new DoubleKeyedHashMap();
     private final DoubleKeyedHashMap dirtyContexts = new DoubleKeyedHashMap();
-    private Map managedConnections;
     private InTxCache inTxCache;
 
+    public abstract boolean getRollbackOnly() throws SystemException;
+
+    public abstract void setRollbackOnly() throws SystemException;
+
     public abstract void suspend() throws SystemException;
 
     public abstract void resume() throws SystemException, InvalidTransactionException;
@@ -73,21 +70,51 @@
         }
     }
 
-    public final void unassociate(Object containerId, Object id) throws Exception {
-        associatedContexts.remove(containerId, id);
-        dirtyContexts.remove(containerId, id);
+    public final void unassociate(InstanceContext context) throws Throwable {
+        associatedContexts.remove(context.getContainerId(), context.getId());
+        context.unassociate();
+    }
+
+    public final void unassociate(Object containerId, Object id) throws Throwable {
+        InstanceContext context = (InstanceContext) associatedContexts.remove(containerId,
id);
+        if (context != null) {
+            context.unassociate();
+        }
+    }
+
+    public final InstanceContext getContext(Object containerId, Object id) {
+        return (InstanceContext) associatedContexts.get(containerId, id);
+    }
+
+    protected final ArrayList getAssociatedContexts() {
+        return new ArrayList(associatedContexts.values());
+    }
+
+    protected final void unassociateAll() {
+        ArrayList toFlush = getAssociatedContexts();
+        for (Iterator i = toFlush.iterator(); i.hasNext();) {
+            InstanceContext context = (InstanceContext) i.next();
+            try {
+                context.unassociate();
+            } catch (Throwable throwable) {
+                log.warn("Error while unassociating instance from transaction context: "
+ context, throwable);
+            }
+        }
     }
 
-    public final InstanceContext beginInvocation(InstanceContext context) {
+    public final InstanceContext beginInvocation(InstanceContext context) throws Throwable
{
         if (context.getId() != null) {
+            associate(context);
             dirtyContexts.put(context.getContainerId(), context.getId(), context);
         }
+        context.enter();
         InstanceContext caller = currentContext;
         currentContext = context;
         return caller;
     }
 
     public final void endInvocation(InstanceContext caller) {
+        currentContext.exit();
         currentContext = caller;
     }
 
@@ -97,7 +124,9 @@
             dirtyContexts.clear();
             for (Iterator i = toFlush.iterator(); i.hasNext();) {
                 InstanceContext context = (InstanceContext) i.next();
-                context.flush();
+                if (!context.isDead()) {
+                    context.flush();
+                }
             }
         }
         if (currentContext != null && currentContext.getId() != null) {
@@ -108,42 +137,6 @@
         }
     }
 
-    protected void beforeCommit() throws Throwable {
-        // @todo allow for enrollment during pre-commit
-        ArrayList toFlush = new ArrayList(associatedContexts.values());
-        for (Iterator i = toFlush.iterator(); i.hasNext();) {
-            InstanceContext context = (InstanceContext) i.next();
-            context.beforeCommit();
-        }
-    }
-
-    protected void afterCommit(boolean status) throws Throwable {
-        Throwable firstThrowable = null;
-        ArrayList toFlush = new ArrayList(associatedContexts.values());
-        for (Iterator i = toFlush.iterator(); i.hasNext();) {
-            InstanceContext context = (InstanceContext) i.next();
-            try {
-                context.afterCommit(status);
-            } catch (Throwable e) {
-                if (firstThrowable == null) {
-                    firstThrowable = e;
-                }
-            }
-        }
-
-        if (firstThrowable instanceof Error) {
-            throw (Error) firstThrowable;
-        } else if (firstThrowable instanceof Exception) {
-            throw (Exception) firstThrowable;
-        } else if (firstThrowable != null) {
-            throw (SystemException) new SystemException().initCause(firstThrowable);
-        }
-    }
-
-    public final InstanceContext getContext(Object containerId, Object id) {
-        return (InstanceContext) associatedContexts.get(containerId, id);
-    }
-
     public final void setInTxCache(InTxCache inTxCache) {
         this.inTxCache = inTxCache;
     }
@@ -151,42 +144,4 @@
     public final InTxCache getInTxCache() {
         return inTxCache;
     }
-
-    //Geronimo connector framework support
-    public void setManagedConnectionInfo(ConnectionReleaser key, Object info) {
-        if (managedConnections == null) {
-            managedConnections = new HashMap();
-        }
-        managedConnections.put(key, info);
-    }
-
-    public Object getManagedConnectionInfo(ConnectionReleaser key) {
-        if (managedConnections == null) {
-            return null;
-        }
-        return managedConnections.get(key);
-    }
-
-    /**
-     * determines if the transaction is in a pre-prepared state
-     * of STATUS_ACTIVE or STATUS_MARKED_ROLLBACK.
-     * @return true if more work can be done in the transaction (although it might be forced
to roll back)
-     */
-    public abstract boolean isActive();
-
-    public abstract Transaction getTransaction();
-
-    protected void connectorAfterCommit() {
-        if (managedConnections != null) {
-            for (Iterator entries = managedConnections.entrySet().iterator(); entries.hasNext();)
{
-                Map.Entry entry = (Map.Entry) entries.next();
-                ConnectionReleaser key = (ConnectionReleaser) entry.getKey();
-                key.afterCompletion(entry.getValue());
-            }
-            //If BeanTransactionContext never reuses the same instance for sequential BMT,
this
-            //clearing is unnecessary.
-            managedConnections.clear();
-        }
-    }
-
 }

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/UnspecifiedTransactionContext.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/UnspecifiedTransactionContext.java?view=diff&r1=155375&r2=155376
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/UnspecifiedTransactionContext.java
(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/UnspecifiedTransactionContext.java
Fri Feb 25 15:10:24 2005
@@ -17,16 +17,18 @@
 
 package org.apache.geronimo.transaction.context;
 
-import javax.transaction.Transaction;
-
-import org.apache.geronimo.transaction.ConnectionReleaser;
-
-
 /**
  * @version $Rev$ $Date$
  */
 public class UnspecifiedTransactionContext extends TransactionContext {
-    public void begin() {
+    private boolean failed = false;
+
+    public boolean getRollbackOnly() {
+        return failed;
+    }
+
+    public void setRollbackOnly() {
+        this.failed = true;
     }
 
     public void suspend() {
@@ -36,33 +38,28 @@
     }
 
     public boolean commit() {
+        complete();
+        return true;
+    }
+
+    public void rollback() {
+        setRollbackOnly();
+        complete();
+    }
+
+    private void complete() {
         try {
-            flushState();
+            if (!failed) {
+                flushState();
+            }
         } catch (Error e) {
             throw e;
         } catch (RuntimeException re) {
             throw re;
         } catch (Throwable e) {
             log.error("Unable to flush state, continuing", e);
+        } finally {
+            unassociateAll();
         }
-        return true;
-    }
-
-    public void rollback() {
-    }
-
-    public void setManagedConnectionInfo(ConnectionReleaser key, Object info) {
-    }
-
-    public Object getManagedConnectionInfo(ConnectionReleaser key) {
-        return null;
-    }
-
-    public boolean isActive() {
-        return false;
-    }
-
-    public Transaction getTransaction() {
-        return null;
     }
 }



Mime
View raw message