[jboss-cvs] JBossCache/tests/functional/org/jboss/cache/transaction ...
Manik Surtani
msurtani at jboss.com
Mon Jan 8 20:24:16 EST 2007
User: msurtani
Date: 07/01/08 20:24:16
Added: tests/functional/org/jboss/cache/transaction Tag:
Branch_JBossCache_1_4_0
AsyncRollbackTransactionManagerLookup.java
AsyncRollbackTxTest.java
AsyncRollbackTransactionManager.java
Log:
JBCACHE-923
Revision Changes Path
No revision
No revision
1.1.2.1 +14 -0 JBossCache/tests/functional/org/jboss/cache/transaction/Attic/AsyncRollbackTransactionManagerLookup.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: AsyncRollbackTransactionManagerLookup.java
===================================================================
RCS file: AsyncRollbackTransactionManagerLookup.java
diff -N AsyncRollbackTransactionManagerLookup.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ AsyncRollbackTransactionManagerLookup.java 9 Jan 2007 01:24:16 -0000 1.1.2.1
@@ -0,0 +1,14 @@
+package org.jboss.cache.transaction;
+
+import org.jboss.cache.TransactionManagerLookup;
+
+import javax.transaction.TransactionManager;
+
+public class AsyncRollbackTransactionManagerLookup implements TransactionManagerLookup
+{
+ public TransactionManager getTransactionManager() throws Exception
+ {
+ return AsyncRollbackTransactionManager.getInstance();
+ }
+
+}
\ No newline at end of file
1.1.2.1 +228 -0 JBossCache/tests/functional/org/jboss/cache/transaction/Attic/AsyncRollbackTxTest.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: AsyncRollbackTxTest.java
===================================================================
RCS file: AsyncRollbackTxTest.java
diff -N AsyncRollbackTxTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ AsyncRollbackTxTest.java 9 Jan 2007 01:24:16 -0000 1.1.2.1
@@ -0,0 +1,228 @@
+package org.jboss.cache.transaction;
+
+import junit.framework.TestCase;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.TreeCache;
+
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+/**
+ * Test behaviour of async rollback timeouted transaction
+ *
+ * @author <a href="mailto:jhalat at infovide.pl">Jacek Halat</a>
+ * @since 1.4.0
+ */
+public class AsyncRollbackTxTest extends TestCase
+{
+ private TreeCache cache;
+ private TransactionManager tm;
+ private Fqn fqn = Fqn.fromString("/test");
+
+ protected void setUp() throws Exception
+ {
+ cache = new TreeCache();
+
+ cache.setTransactionManagerLookupClass("org.jboss.cache.transaction.AsyncRollbackTransactionManagerLookup");
+ cache.startService();
+ tm = cache.getTransactionManager();
+ tm.setTransactionTimeout(2);
+ }
+
+ protected void tearDown()
+ {
+ try
+ {
+ if (tm != null && tm.getTransaction() != null)
+ {
+ try
+ {
+ tm.rollback();
+ }
+ catch (SystemException e)
+ {
+ // do nothing
+ }
+ }
+ }
+ catch (SystemException e)
+ {
+ // do nothing
+ }
+ if (cache != null) cache.stopService();
+ cache = null;
+ tm = null;
+ }
+
+ public void testCommitCreationInSameTx() throws Exception
+ {
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ tm.begin();
+ cache.put(fqn, "k", "v");
+ assertEquals(2, cache.getNumberOfLocksHeld());
+ Thread.sleep(2500);
+ tm.commit();
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ }
+
+ public void testRollbackCreationInSameTx() throws Exception
+ {
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ tm.begin();
+ cache.put(fqn, "k", "v");
+ assertEquals(2, cache.getNumberOfLocksHeld());
+ Thread.sleep(2500);
+ tm.rollback();
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ }
+
+
+ private void doTest(boolean commit, boolean writeLock) throws Exception
+ {
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ cache.put(fqn, "k", "v");//Executed in Not transactional context
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ SeparateThread t = new SeparateThread(commit, writeLock);
+ t.start();
+ t.join();
+ if (t.getException() != null)
+ {
+ throw t.getException();
+ }
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ assertEquals("v", cache.get(fqn, "k"));
+ }
+
+ public void testRollbackCreationInDifferentTxReadLock() throws Exception
+ {
+ doTest(false, false);
+ }
+
+ public void testCommitCreationInDifferentTxReadLock() throws Exception
+ {
+ doTest(true, false);
+ }
+
+ public void testRollbackCreationInDifferentTxWriteLock() throws Exception
+ {
+ doTest(false, true);
+ }
+
+ public void testCommitCreationInDifferentTxWriteLock() throws Exception
+ {
+ doTest(true, true);
+ }
+
+ public void testTxTimeoutAndPutAfter() throws Exception
+ {
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ tm.begin();
+ cache.put(fqn, "k", "v");
+ assertEquals(2, cache.getNumberOfLocksHeld());
+ assertNotNull(tm.getTransaction());
+ Thread.sleep(2500);
+ tm.rollback();
+ assertNull(tm.getTransaction());
+ assertEquals(0, cache.getNumberOfLocksHeld());
+
+ // make sure the node was NOT added!!
+ assertFalse(cache.exists(fqn));
+ // even in a "deleted" form
+ assertNull(cache.peek(fqn));
+
+ //Put not some data into cache. Because no transaction exist
+ //no locks should be helds after this line, correct?
+
+ cache.put(fqn, "k", "v");
+ //On version 1.4.0SP1 cache.getNumberOfLocksHeld()==1
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ }
+
+
+ public void testTxTimeoutAndPutGetAfter() throws Exception
+ {
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ tm.begin();
+ cache.put(fqn, "k", "v");
+ assertEquals(2, cache.getNumberOfLocksHeld());
+ assertNotNull(tm.getTransaction());
+ Thread.sleep(2500);
+ tm.rollback();
+ assertNull(tm.getTransaction());
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ //Put not some data into cache. Because no transaction exist
+ //no locks should be helds after this line, correct?
+ cache.put(fqn, "k", "v");
+ cache.get(fqn, "k");
+ //Because this thread is Owner of lock, read this node can be readed
+ //but when we try read this value from another thread (another thread is of course NOT lock owner)
+ //we got...
+ SeparateThread t = new SeparateThread(false, false);
+ t.start();
+ t.join();
+ if (t.getException() != null)
+ {
+ throw t.getException();
+ }
+ //...TimeoutException. This happend On version 1.4.0SP1.
+ //org.jboss.cache.lock.TimeoutException: failure acquiring lock: fqn=/test, caller=GlobalTransaction:<null>:2, lock=write owner=GlobalTransaction:<null>:1 (activeReaders=0, activeWriter=Thread[main,5,main], waitingReaders=0, waitingWriters=0, waitingUpgrader=0)
+ //at org.jboss.cache.Node.acquire(Node.java:407)
+
+ }
+
+
+ private class SeparateThread extends Thread
+ {
+ Exception e = null;
+ boolean commit, writeLock;
+
+
+ public SeparateThread(boolean commit, boolean writeLock)
+ {
+ this.commit = commit;
+ this.writeLock = writeLock;
+ }
+
+ public Exception getException()
+ {
+ return e;
+ }
+
+ public void run()
+ {
+ try
+ {
+ tm.begin();
+ if (writeLock)
+ {
+ cache.put(fqn, "k", "v2");// obtain write lock on node
+ }
+ else
+ {
+ cache.get(fqn, "k");// obtain read lock on node
+ }
+
+ // sleep to ensure tx times out.
+ sleep(2500);
+
+ if (commit)
+ {
+ tm.commit();
+ }
+ else
+ {
+ tm.rollback();
+ }
+
+ assertEquals(0, cache.getNumberOfLocksHeld());
+ }
+ catch (Exception e)
+ {
+ this.e = e;
+ }
+ }
+ }
+
+ ;
+}
+
1.1.2.1 +238 -0 JBossCache/tests/functional/org/jboss/cache/transaction/Attic/AsyncRollbackTransactionManager.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: AsyncRollbackTransactionManager.java
===================================================================
RCS file: AsyncRollbackTransactionManager.java
diff -N AsyncRollbackTransactionManager.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ AsyncRollbackTransactionManager.java 9 Jan 2007 01:24:16 -0000 1.1.2.1
@@ -0,0 +1,238 @@
+package org.jboss.cache.transaction;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+public class AsyncRollbackTransactionManager extends DummyTransactionManager
+{
+ static AsyncRollbackTransactionManager instance = null;
+ private static Log log = LogFactory.getLog(AsyncRollbackTransactionManager.class);
+
+ public static DummyTransactionManager getInstance()
+ {
+ if (instance == null)
+ {
+ instance = new AsyncRollbackTransactionManager();
+ try
+ {
+ Properties p = new Properties();
+ p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
+ Context ctx = new InitialContext(p);
+ ctx.bind("java:/TransactionManager", instance);
+ ctx.bind("UserTransaction", new DummyUserTransaction(instance));
+ }
+ catch (NamingException e)
+ {
+ log.error("binding of DummyTransactionManager failed", e);
+ }
+ }
+ return instance;
+ }
+
+ private Thread timedOutTransactionsChecker = null;
+ private int timeout = 30;
+ private Map txMap = new HashMap();
+
+ public void setTransactionTimeout(int seconds) throws SystemException
+ {
+ this.timeout = seconds;
+ }
+
+ public AsyncRollbackTransactionManager()
+ {
+ timedOutTransactionsChecker = new TimedOutTransactionsChecker();
+ timedOutTransactionsChecker.start();
+ }
+
+ private class TimedOutTransactionsChecker extends Thread
+ {
+ private boolean running;
+
+ public TimedOutTransactionsChecker()
+ {
+ }
+
+ public void run()
+ {
+ running = true;
+ while (running)
+ {
+ try
+ {
+ Thread.sleep(500);
+ synchronized (this)
+ {
+ Iterator iterator = txMap.values().iterator();
+ do
+ {
+ if (!iterator.hasNext())
+ {
+ break;
+ }
+ AsyncRollbackTransaction t = (AsyncRollbackTransaction) iterator.next();
+ try
+ {
+ t.wakeUp();
+ }
+ catch (SystemException e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+ while (true);
+ }
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+ }
+
+ }
+
+ public void begin() throws NotSupportedException, SystemException
+ {
+ Transaction currentTx;
+ if ((currentTx = getTransaction()) != null)
+ {
+ throw new NotSupportedException(Thread.currentThread() +
+ " is already associated with a transaction (" + currentTx + ")");
+ }
+ AsyncRollbackTransaction tx = new AsyncRollbackTransaction(this, timeout);
+ setTransaction(tx);
+ txMap.put(new Long(tx.generateTransactionId()), tx);
+ }
+
+
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ removeTxFromMap((AsyncRollbackTransaction) getTransaction());
+ super.rollback();
+ }
+
+ public void removeTxFromMap(AsyncRollbackTransaction tx) throws SystemException
+ {
+ if (tx != null)
+ {
+ txMap.remove(new Long(tx.getTransactionId()));
+ }
+ }
+
+
+ public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+ {
+ AsyncRollbackTransaction tx = (AsyncRollbackTransaction) getTransaction();
+ if (tx != null)
+ {
+ txMap.remove(new Long(tx.getTransactionId()));
+ }
+ super.commit();
+ }
+
+
+ public void resume(Transaction tx) throws InvalidTransactionException, IllegalStateException, SystemException
+ {
+ //TODO Not implemented TX timeout counting
+ super.resume(tx);
+ }
+
+
+ public Transaction suspend() throws SystemException
+ {
+ //TODO Not implemented TX timeout counting
+ return super.suspend();
+ }
+
+ static class AsyncRollbackTransaction extends DummyTransaction
+ {
+ private static long transactionNums = 0;
+
+ private long transactionId;
+
+ private long beginTimeMillis;
+
+ private int timeoutSec;
+
+ public AsyncRollbackTransaction(DummyBaseTransactionManager tm, int timeout)
+ {
+ super(tm);
+ this.timeoutSec = timeout;
+ this.beginTimeMillis = System.currentTimeMillis();
+ }
+
+ /**
+ * @return the transactionId
+ */
+ public long getTransactionId()
+ {
+ return transactionId;
+ }
+
+ public long generateTransactionId()
+ {
+ long result = 0;
+ synchronized (AsyncRollbackTransaction.class)
+ {
+ transactionNums++;
+ result = transactionNums;
+ }
+ this.transactionId = result;
+ return result;
+ }
+
+ final int getTimeoutSeconds()
+ {
+ return timeoutSec;
+ }
+
+ protected final void asyncRollback() throws SystemException
+ {
+ Thread asyncRollbackThread = new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ rollback();
+ }
+ catch (Exception exception)
+ {
+ }
+ }
+ };
+ ((AsyncRollbackTransactionManager) tm_).removeTxFromMap(this);
+ asyncRollbackThread.start();
+ }
+
+ public void wakeUp() throws SystemException
+ {
+ if (isTransactionTimedOut())
+ {
+ asyncRollback();
+ }
+ }
+
+ private boolean isTransactionTimedOut()
+ {
+ return (System.currentTimeMillis() - beginTimeMillis) > (timeoutSec * 1000);
+ }
+ }
+
+
+}
\ No newline at end of file
More information about the jboss-cvs-commits
mailing list