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 2005/01/27 23:56:23 UTC
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
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());