[jbosscache-commits] JBoss Cache SVN: r8148 - in core/trunk/src: test/java/org/jboss/cache/api/mvcc and 1 other directory.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Wed Aug 5 06:54:02 EDT 2009


Author: galder.zamarreno at jboss.com
Date: 2009-08-05 06:54:02 -0400 (Wed, 05 Aug 2009)
New Revision: 8148

Added:
   core/trunk/src/test/java/org/jboss/cache/api/mvcc/PutRemoveTest.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/mvcc/MVCCNodeHelper.java
Log:
[JBCACHE-1519] (ClassCastException in ReadCommittedNode.markForUpdate()) Fixed by making sure that when parent node is updated after a removal, the parent is wrapped in a NodeReference if read committed is in use.

Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/MVCCNodeHelper.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/MVCCNodeHelper.java	2009-08-05 10:36:32 UTC (rev 8147)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/MVCCNodeHelper.java	2009-08-05 10:54:02 UTC (rev 8148)
@@ -35,6 +35,7 @@
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.factories.annotations.NonVolatile;
 import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.lock.IsolationLevel;
 import org.jboss.cache.lock.LockManager;
 import static org.jboss.cache.lock.LockType.WRITE;
 import org.jboss.cache.lock.TimeoutException;
@@ -51,6 +52,7 @@
  * locking, if necessary.
  *
  * @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
+ * @author Galder Zamarreño
  * @since 3.0
  */
 @NonVolatile
@@ -196,7 +198,6 @@
             // create a copy of the underlying node
             n.markForUpdate(dataContainer, writeSkewCheck);
          }
-         if (trace) log.trace("Retrieving wrapped node " + fqn);
          if (n.isDeleted() && createIfAbsent) {
             if (trace) log.trace("Node is deleted in current scope.  Need to un-delete.");
             n.markAsDeleted(false);
@@ -335,7 +336,16 @@
          // update child ref on parent to point to child as this is now a copy.
          if (parentLockNeeded && (needToCopyNode || needToCopyParent)) {
             if (parent == null) throw new NodeNotExistsException("Parent node " + parentFqn + " does not exist!");
-            parent.getDelegationTarget().addChild(node.getDelegationTarget());
+            InternalNode ref = null;
+            if (configuration.getIsolationLevel() == IsolationLevel.READ_COMMITTED)
+            {
+               ref = new NodeReference(node.getDelegationTarget());
+            }
+            else
+            {
+               ref = node.getDelegationTarget();
+            }
+            parent.getDelegationTarget().addChild(ref);
          }
 
          // now deal with children.

Added: core/trunk/src/test/java/org/jboss/cache/api/mvcc/PutRemoveTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/mvcc/PutRemoveTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/api/mvcc/PutRemoveTest.java	2009-08-05 10:54:02 UTC (rev 8148)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+package org.jboss.cache.api.mvcc;
+
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.UnitTestCacheFactory;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.UnitTestConfigurationFactory;
+import org.jboss.cache.lock.IsolationLevel;
+import org.jboss.cache.transaction.DummyTransactionManagerLookup;
+import org.jboss.cache.util.TestingUtil;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.TransactionManager;
+
+ at Test(groups = { "functional" }, testName = "api.mvcc.PutRemoveTest")
+public class PutRemoveTest
+{
+   private CacheSPI<String, String> cache;
+   private TransactionManager tm;
+
+   @BeforeMethod(alwaysRun = true)
+   public void setUp() throws Exception
+   {
+      UnitTestCacheFactory<String, String> factory = new UnitTestCacheFactory<String, String>();
+      Configuration conf = UnitTestConfigurationFactory.createConfiguration(Configuration.CacheMode.LOCAL, true);
+      conf.setIsolationLevel(IsolationLevel.READ_COMMITTED);
+      conf.setLockParentForChildInsertRemove(true);
+      conf.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+      cache = (CacheSPI<String, String>) factory.createCache(conf, true, getClass());
+      tm = cache.getTransactionManager();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   public void tearDown() throws Exception
+   {
+      TestingUtil.killCaches(cache);
+   }
+
+   public void testPutRemove() throws Exception
+   {
+      Fqn fqn = Fqn.fromElements("test", "a", "b");
+
+      for (int i = 0; i < 5; i++)
+      {
+         System.out.println("i == " + i + " [1]");
+         tm.begin();
+         check(fqn);
+         tm.commit();
+
+         System.out.println("i == " + i + " [2]");
+         tm.begin();
+         // the exception is in remove() on the SECOND pass!
+         if (remove(fqn))
+         {
+            check(fqn);
+         }
+         tm.commit();
+      }
+   }
+
+   private void check(Fqn fqn)
+   {
+      if (cache.get(fqn.getAncestor(1), "a") == null)
+      {
+         cache.put(fqn.getAncestor(1), "key-a", "value-a");
+         cache.put(fqn, "test-key-a", "value-a");
+      }
+   }
+
+   private boolean remove(Fqn fqn)
+   {
+      return cache.removeNode(fqn.getAncestor(1));
+   }
+}



More information about the jbosscache-commits mailing list