[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