[exo-jcr-commits] exo-jcr SVN: r908 - jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache.

do-not-reply at jboss.org do-not-reply at jboss.org
Mon Nov 30 11:41:43 EST 2009


Author: nzamosenchuk
Date: 2009-11-30 11:41:43 -0500 (Mon, 30 Nov 2009)
New Revision: 908

Modified:
   jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java
Log:
EXOJCR-243: reimplemented addLockData() method using Node.putIfAbent() to prevent concurrency race situation.

Modified: jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java
===================================================================
--- jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java	2009-11-30 11:57:21 UTC (rev 907)
+++ jcr/branches/1.12.0-JBC/component/core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/JBossCacheStorageConnection.java	2009-11-30 16:41:43 UTC (rev 908)
@@ -300,7 +300,7 @@
       InvalidItemStateException, IllegalStateException
    {
       startBatch();
-      
+
       // check if parent is cached
       Node<Serializable, Object> parent = nodesRoot.getChild(makeNodeFqn(data.getParentIdentifier()));
       if (parent == null)
@@ -1339,33 +1339,31 @@
       {
          throw new RepositoryException("Lock data to write can't be null!");
       }
-      // check that there is no lock data for given node
-      Node<Serializable, Object> node = locksRoot.getChild(makeNodeFqn(lockData.getNodeIdentifier()));
-      // node is not null: check if lockData exists
-      if (node != null)
+      // addChild will add if absent or return old if present
+      Node<Serializable, Object> node = locksRoot.addChild(makeNodeFqn(lockData.getNodeIdentifier()));
+      // this will prevent from deleting by eviction.
+      node.setResident(true);
+
+      // this will return null if success. And old data if something exists...
+      LockData oldLockData = (LockData)node.putIfAbsent(JBossCacheStorage.LOCK_DATA, lockData);
+      // if oldLockData is present (not null):
+      // 1. this is Lock.refresh(): oldLockData and lockData will have the same tokens 
+      // 2. this node is already locked: data-s will have different tokens
+
+      if (oldLockData != null)
       {
-         LockData oldLockData = (LockData)node.get(JBossCacheStorage.LOCK_DATA);
-         // if old data exists and hash differs, then it was newly locked! Exception, can't lock
-         // already locked node.
-         if (oldLockData != null && oldLockData.getTokenHash() != lockData.getTokenHash())
+         // if LockData already present with different lock token, then node has already been locked! 
+         if (oldLockData.getTokenHash() != lockData.getTokenHash())
          {
             throw new LockException("Unable to write lock data. Node [" + lockData.getNodeIdentifier()
                + "] already has LockData!");
          }
+         else
+         {
+            // token is the same, then Lock is just refreshed. Putting new LockData.
+            node.put(JBossCacheStorage.LOCK_DATA, lockData);
+         }
       }
-      else
-      {
-         // JBoss node doesn't exists, create it
-         node = locksRoot.addChild(makeNodeFqn(lockData.getNodeIdentifier()));
-         node.setResident(true);
-      }
-      // try to write LockData 
-      if (node == null)
-      {
-         throw new RepositoryException("Unable to write to cache!");
-      }
-      // this will prevent from deleting it by eviction.
-      node.put(JBossCacheStorage.LOCK_DATA, lockData);
    }
 
    /**



More information about the exo-jcr-commits mailing list