geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From djen...@apache.org
Subject svn commit: r128441 - in geronimo/trunk/modules/transaction/src: java/org/apache/geronimo/transaction/context java/org/apache/geronimo/transaction/manager test/org/apache/geronimo/transaction/manager
Date Thu, 27 Jan 2005 22:56:23 GMT
Author: djencks
Date: Thu Jan 27 14:56:21 2005
New Revision: 128441

URL: http://svn.apache.org/viewcvs?view=rev&rev=128441
Log:
Convert from timer/interrupt based tx timeout to checking the time at commit.  Most of GERONIMO-550.
 I left time unit at milliseconds and avoided the thread local where possible
Added:
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionTimer.java
Modified:
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
   geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/manager/TransactionManagerImplTest.java

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java?view=diff&rev=128441&p1=geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java&r1=128440&p2=geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java&r2=128441
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java
(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java
Thu Jan 27 14:56:21 2005
@@ -291,6 +291,7 @@
         infoFactory.addOperation("newUnspecifiedTransactionContext");
         infoFactory.addOperation("getStatus");
         infoFactory.addOperation("setRollbackOnly");
+        infoFactory.addOperation("setTransactionTimeout", new Class[] {int.class});
 
         infoFactory.addReference("TransactionManager", ExtendedTransactionManager.class);
         infoFactory.addReference("XidImporter", XidImporter.class);

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java?view=diff&rev=128441&p1=geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java&r1=128440&p2=geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java&r2=128441
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
Thu Jan 27 14:56:21 2005
@@ -24,7 +24,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.TimerTask;
 import javax.transaction.HeuristicMixedException;
 import javax.transaction.HeuristicRollbackException;
 import javax.transaction.RollbackException;
@@ -44,12 +43,13 @@
  *
  * @version $Rev$ $Date$
  */
-public class TransactionImpl extends TimerTask implements Transaction {
+public class TransactionImpl implements Transaction {
     private static final Log log = LogFactory.getLog("Transaction");
 
     private final XidFactory xidFactory;
     private final Xid xid;
     private final TransactionLog txnLog;
+    private final long timeout;
     private final List syncList = new ArrayList(5);
     private final LinkedList resourceManagers = new LinkedList();
     private final IdentityHashMap activeXaResources = new IdentityHashMap(3);
@@ -57,16 +57,15 @@
     private int status = Status.STATUS_NO_TRANSACTION;
     private Object logMark;
 
-    private Thread currentThread;
-
-    TransactionImpl(XidFactory xidFactory, TransactionLog txnLog) throws SystemException
{
-        this(xidFactory.createXid(), xidFactory, txnLog);
+    TransactionImpl(XidFactory xidFactory, TransactionLog txnLog, long transactionTimeoutMilliseconds)
throws SystemException {
+        this(xidFactory.createXid(), xidFactory, txnLog, transactionTimeoutMilliseconds);
     }
 
-    TransactionImpl(Xid xid, XidFactory xidFactory, TransactionLog txnLog) throws SystemException
{
+    TransactionImpl(Xid xid, XidFactory xidFactory, TransactionLog txnLog, long transactionTimeoutMilliseconds)
throws SystemException {
         this.xidFactory = xidFactory;
         this.txnLog = txnLog;
         this.xid = xid;
+        this.timeout = transactionTimeoutMilliseconds + TransactionTimer.getCurrentTime();
         try {
             txnLog.begin(xid);
         } catch (LogException e) {
@@ -84,6 +83,8 @@
         this.txnLog = txLog;
         this.xid = xid;
         status = Status.STATUS_PREPARED;
+        //TODO is this a good idea?
+        this.timeout = Long.MAX_VALUE;
     }
 
     public synchronized int getStatus() throws SystemException {
@@ -221,10 +222,23 @@
         beforePrepare();
 
         try {
+                      boolean timedout = false;
+                      if (TransactionTimer.getCurrentTime() > timeout)
+                      {
+                          status = Status.STATUS_MARKED_ROLLBACK;
+                          timedout = true;
+                      }
+
             if (status == Status.STATUS_MARKED_ROLLBACK) {
                 rollbackResources(resourceManagers);
-                cancel();
-                throw new RollbackException("Unable to commit");
+                              if(timedout)
+                              {
+                                  throw new RollbackException("Transaction timout");
+                              }
+                              else
+                              {
+                                  throw new RollbackException("Unable to commit");
+                              }
             }
             synchronized (this) {
                 if (status == Status.STATUS_ACTIVE) {
@@ -248,7 +262,6 @@
                 synchronized (this) {
                     status = Status.STATUS_COMMITTED;
                 }
-                cancel();
                 return;
             }
 
@@ -256,7 +269,6 @@
             if (resourceManagers.size() == 1) {
                 TransactionBranch manager = (TransactionBranch) resourceManagers.getFirst();
                 try {
-                    cancel();
                     manager.getCommitter().commit(manager.getBranchId(), true);
                     synchronized (this) {
                         status = Status.STATUS_COMMITTED;
@@ -298,7 +310,6 @@
                 if (status == Status.STATUS_ACTIVE) {
                     if (resourceManagers.size() == 0) {
                         // nothing to commit
-                        cancel();
                         status = Status.STATUS_COMMITTED;
                         return result;
                     } else {
@@ -398,9 +409,6 @@
                 status = Status.STATUS_PREPARED;
             }
         }
-        //cancel timeout.
-        cancel();
-
         // log our decision
         if (willCommit && !resourceManagers.isEmpty()) {
             try {
@@ -418,7 +426,6 @@
     }
 
     public void rollback() throws IllegalStateException, SystemException {
-        cancel();
         List rms;
         synchronized (this) {
             switch (status) {
@@ -622,23 +629,6 @@
         TransactionBranch manager = new TransactionBranch(xaRes, branchId);
         resourceManagers.add(manager);
         return manager;
-    }
-
-
-    //TimerTask implementation
-    public synchronized void run() {
-        try {
-            setRollbackOnly();
-            if (currentThread != null) {
-                currentThread.interrupt();
-            }
-        } catch (SystemException e) {
-            //in the wrong state.
-        }
-    }
-
-    public synchronized void setCurrentThread(Thread currentThread) {
-        this.currentThread = currentThread;
     }
 
     private static class TransactionBranch implements TransactionBranchInfo {

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java?view=diff&rev=128441&p1=geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java&r1=128440&p2=geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java&r2=128441
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
Thu Jan 27 14:56:21 2005
@@ -23,7 +23,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Timer;
 import javax.transaction.HeuristicMixedException;
 import javax.transaction.HeuristicRollbackException;
 import javax.transaction.InvalidTransactionException;
@@ -42,13 +41,12 @@
 import org.apache.geronimo.gbean.ReferenceCollection;
 import org.apache.geronimo.gbean.ReferenceCollectionEvent;
 import org.apache.geronimo.gbean.ReferenceCollectionListener;
+import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
 import org.apache.geronimo.transaction.ExtendedTransactionManager;
 import org.apache.geronimo.transaction.log.UnrecoverableLog;
-import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
 
 /**
  * Simple implementation of a transaction manager.
- * TODO shut down timer gracefully
  *
  * @version $Rev$ $Date$
  */
@@ -58,7 +56,6 @@
     private final int defaultTransactionTimeoutMilliseconds;
     private final ThreadLocal transactionTimeoutMilliseconds = new ThreadLocal();
     private final ThreadLocal threadTx = new ThreadLocal();
-    private final Timer timeoutTimer = new Timer(true);
     private static final Log recoveryLog = LogFactory.getLog("RecoveryController");
     final Recovery recovery;
     final ReferenceCollection resourceManagers;
@@ -130,17 +127,17 @@
         if (getStatus() != Status.STATUS_NO_TRANSACTION) {
             throw new NotSupportedException("Nested Transactions are not supported");
         }
-        TransactionImpl tx = new TransactionImpl(xidFactory, transactionLog);
-        timeoutTimer.schedule(tx, getTransactionTimeoutMilliseconds(transactionTimeoutMilliseconds));
+        TransactionImpl tx = new TransactionImpl(xidFactory, transactionLog, getTransactionTimeoutMilliseconds(transactionTimeoutMilliseconds));
+//        timeoutTimer.schedule(tx, getTransactionTimeoutMilliseconds(transactionTimeoutMilliseconds));
         threadTx.set(tx);
-        ((TransactionImpl) tx).setCurrentThread(Thread.currentThread());
+                // Todo: Verify if this is correct thing to do. Use default timeout for next
transaction.
+        this.transactionTimeoutMilliseconds.set(null);
         return tx;
     }
 
     public Transaction suspend() throws SystemException {
         Transaction tx = getTransaction();
         if (tx != null) {
-            ((TransactionImpl) tx).setCurrentThread(null);
         }
         threadTx.set(null);
         return tx;
@@ -154,7 +151,6 @@
             throw new InvalidTransactionException("Cannot resume foreign transaction: " +
tx);
         }
         threadTx.set(tx);
-        ((TransactionImpl) tx).setCurrentThread(Thread.currentThread());
     }
 
     public void setRollbackOnly() throws IllegalStateException, SystemException {
@@ -174,7 +170,6 @@
             tx.commit();
         } finally {
             threadTx.set(null);
-            ((TransactionImpl) tx).setCurrentThread(null);
         }
     }
 
@@ -187,7 +182,6 @@
             tx.rollback();
         } finally {
             threadTx.set(null);
-            ((TransactionImpl) tx).setCurrentThread(null);
         }
     }
 
@@ -196,8 +190,7 @@
         if (transactionTimeoutMilliseconds < 0) {
             throw new SystemException("transaction timeout must be positive or 0 to reset
to default");
         }
-        TransactionImpl tx = new TransactionImpl(xid, xidFactory, transactionLog);
-        timeoutTimer.schedule(tx, getTransactionTimeoutMilliseconds(transactionTimeoutMilliseconds));
+        TransactionImpl tx = new TransactionImpl(xid, xidFactory, transactionLog, getTransactionTimeoutMilliseconds(transactionTimeoutMilliseconds));
         return tx;
     }
 
@@ -249,7 +242,7 @@
         }
     }
 
-    private long getTransactionTimeoutMilliseconds(long transactionTimeoutMilliseconds) {
+    long getTransactionTimeoutMilliseconds(long transactionTimeoutMilliseconds) {
         if (transactionTimeoutMilliseconds != 0) {
             return transactionTimeoutMilliseconds;
         }

Added: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionTimer.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionTimer.java?view=auto&rev=128441
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionTimer.java
Thu Jan 27 14:56:21 2005
@@ -0,0 +1,54 @@
+/**
+ *
+ * Copyright 2003-2004 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;
+
+/**
+ * TODO improve shutdown
+ *
+ * @version $Revision:  $ $Date:  $
+ */
+public class TransactionTimer {
+    private static volatile long currentTime;
+
+    private static class CurrentTime extends Thread {
+        protected CurrentTime() {
+            currentTime = System.currentTimeMillis();
+        }
+
+        public void run() {
+            for (; ;) {
+                currentTime = System.currentTimeMillis();
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    // Ignore exception
+                }
+            }
+        }
+    }
+
+    static {
+        CurrentTime tm = new CurrentTime();
+        tm.setDaemon(true);
+        tm.start();
+    }
+
+    public static long getCurrentTime() {
+        return currentTime;
+    }
+
+}

Modified: geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/manager/TransactionManagerImplTest.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/manager/TransactionManagerImplTest.java?view=diff&rev=128441&p1=geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/manager/TransactionManagerImplTest.java&r1=128440&p2=geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/manager/TransactionManagerImplTest.java&r2=128441
==============================================================================
--- geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/manager/TransactionManagerImplTest.java
(original)
+++ geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/manager/TransactionManagerImplTest.java
Thu Jan 27 14:56:21 2005
@@ -293,6 +293,30 @@
         assertEquals(xid, recovered.keySet().iterator().next());
     }
 
+      public void testTimeout() throws Exception
+      {
+          long timeout = tm.getTransactionTimeoutMilliseconds(0L);
+          tm.setTransactionTimeout((int)timeout/4000);
+          tm.begin();
+          System.out.println("Test to sleep for" + timeout + " secs");
+          Thread.sleep(timeout);
+          try
+          {
+              tm.commit();
+              fail("Tx Should get Rollback exception");
+          }catch(RollbackException rex)
+          {
+              // Caught expected exception
+          }
+
+          // Now test if the default timeout is active
+          tm.begin();
+          System.out.println("Test to sleep for" + (timeout/2) + " secs");
+          Thread.sleep((timeout/2));
+          tm.commit();
+          // Its a failure if exception occurs.
+      }
+
     public void testResourceManagerContract() throws Exception {
         resourceManagers.add(rm1);
         assertTrue(rm1.areAllResourcesReturned());

Mime
View raw message