[jbosscache-commits] JBoss Cache SVN: r4740 - in core/branches/1.4.X: tests/functional/org/jboss/cache/lock and 2 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Thu Nov 8 10:40:14 EST 2007


Author: manik.surtani at jboss.com
Date: 2007-11-08 10:40:14 -0500 (Thu, 08 Nov 2007)
New Revision: 4740

Added:
   core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/
   core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java
Modified:
   core/branches/1.4.X/src/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
   core/branches/1.4.X/tests/functional/org/jboss/cache/misc/TestingUtil.java
Log:
JBCACHE-1165 - added test and fixed.  No more endless loop and concurrent put/remove issues with Pessimistic Locking.

Modified: core/branches/1.4.X/src/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/interceptors/PessimisticLockInterceptor.java	2007-11-08 15:20:59 UTC (rev 4739)
+++ core/branches/1.4.X/src/org/jboss/cache/interceptors/PessimisticLockInterceptor.java	2007-11-08 15:40:14 UTC (rev 4740)
@@ -118,6 +118,7 @@
             fqn = (Fqn) args[1];
             lock_type = DataNode.LOCK_TYPE_WRITE;
             recursive = true; // remove node and *all* child nodes
+            createIfNotExists = true;
             // JBCACHE-871 We need to store the node
             storeLockedNode = true;
             break;
@@ -308,6 +309,19 @@
          // Try to acquire the lock; recording that we did if successful
          acquireNodeLock(child_node, owner, gtx, currentLockType, lock_timeout);
 
+         // make sure the lock we acquired isn't on a deleted node/is an orphan!!
+         DataNode repeek = cache.peek(child_node.getFqn());
+         if (repeek != null && child_node != repeek)
+         {
+            log.trace("Was waiting for and obtained a lock on a node that doesn't exist anymore!  Attempting lock acquisition again.");
+            // we have an orphan!! Lose the unnecessary lock and re-acquire the lock (and potentially recreate the node).
+            child_node.getLock().release(owner);
+
+            // do the loop again, but don't assign child_node to n so that child_node is processed again.
+            i--;
+            continue;
+         }
+
          if (recursive && isTargetNode(i, treeNodeSize))
          {
             {

Added: core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java	                        (rev 0)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/lock/pessimistic/ConcurrentPutRemoveTest.java	2007-11-08 15:40:14 UTC (rev 4740)
@@ -0,0 +1,104 @@
+package org.jboss.cache.lock.pessimistic;
+
+import junit.framework.TestCase;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.DummyTransactionManagerLookup;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.TreeCache;
+import org.jboss.cache.lock.IsolationLevel;
+import org.jboss.cache.misc.TestingUtil;
+
+import javax.transaction.TransactionManager;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ConcurrentPutRemoveTest extends TestCase
+{
+   private TransactionManager tm;
+
+   private TreeCache cache;
+
+   private final Log log = LogFactory.getLog(ConcurrentPutRemoveTest.class);
+   private List threads;
+
+
+   public void setUp() throws Exception
+   {
+      cache = new TreeCache();
+      cache.setIsolationLevel(IsolationLevel.READ_COMMITTED);
+      cache.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+      cache.setLockAcquisitionTimeout(1000);
+      cache.start();
+      tm = cache.getTransactionManager();
+      threads = new ArrayList();
+   }
+
+   public void tearDown() throws Exception
+   {
+      TestingUtil.killCaches(new TreeCache[]{cache});
+   }
+
+   public void testLock() throws Exception
+   {
+      for (int x = 0; x < 2; x++)
+      {
+         SeparateThread t = new SeparateThread(x);
+         threads.add(t);
+         t.start();
+      }
+      for (Iterator i = threads.iterator(); i.hasNext();)
+      {
+         SeparateThread separateThread = (SeparateThread) i.next();
+         separateThread.join();
+         if (separateThread.getException() != null)
+         {
+            throw separateThread.getException();
+         }
+      }
+   }
+
+   private class SeparateThread extends Thread
+   {
+      Exception e = null;
+
+      private int num = 0;
+
+      public SeparateThread(int num)
+      {
+         this.num = num;
+      }
+
+      public Exception getException()
+      {
+         return e;
+      }
+
+      public void run()
+      {
+         Thread.currentThread().setName("Thread:" + num);
+         try
+         {
+            for (int x = 0; x < 100; x++)
+            {
+               tm.begin();
+               log.warn("Before Remove (" + x + ")");
+               //inside transaction
+               cache.remove(Fqn.fromString("/a"));
+               log.warn("After Remove (" + x + ")");
+               tm.commit();
+               //outside transaction
+               log.warn("Before Put (" + x + ")");
+               cache.put(Fqn.fromString("/a/b/c/d"), "text" + x, "b");
+               log.warn("After Put (" + x + ")");
+            }
+         }
+         catch (Exception e)
+         {
+            this.e = e;
+         }
+      }
+   }
+
+}

Modified: core/branches/1.4.X/tests/functional/org/jboss/cache/misc/TestingUtil.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/misc/TestingUtil.java	2007-11-08 15:20:59 UTC (rev 4739)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/misc/TestingUtil.java	2007-11-08 15:40:14 UTC (rev 4740)
@@ -7,12 +7,13 @@
 
 package org.jboss.cache.misc;
 
-import java.util.Vector;
-import java.io.File;
-
+import org.jboss.cache.Fqn;
 import org.jboss.cache.TreeCache;
 import org.jboss.cache.TreeCacheMBean;
 
+import java.io.File;
+import java.util.Vector;
+
 /**
  * Utilities for unit testing JBossCache.
  * 
@@ -23,6 +24,48 @@
 {
 
    /**
+    * Kills a cache - stops it, clears any data in any cache loaders, and rolls back any associated txs
+    */
+   public static void killCaches(TreeCache[] caches)
+   {
+      if (caches == null) return;
+
+      for (int i = 0; i<caches.length; i++)
+      {
+         TreeCache c = caches[i];
+         if (c != null)
+         {
+            if (c.getTransactionManager() != null)
+            {
+               try
+               {
+                  c.getTransactionManager().rollback();
+               }
+               catch (Exception e)
+               {
+                  // don't care
+               }
+            }
+
+            if (c.getCacheLoader() != null)
+            {
+               try
+               {
+                  c.getCacheLoader().remove(Fqn.ROOT);
+               }
+               catch (Exception e)
+               {
+                  // don't care
+               }
+            }
+
+            c.stop();
+            c.destroy();
+         }
+      }
+   }
+
+   /**
     * Loops, continually calling {@link #areCacheViewsComplete(TreeCache[])}
     * until it either returns true or <code>timeout</code> ms have elapsed.
     * 




More information about the jbosscache-commits mailing list