[jboss-cvs] JBossCache/src/org/jboss/cache/interceptors ...

Manik Surtani msurtani at jboss.com
Fri Nov 24 09:19:30 EST 2006


  User: msurtani
  Date: 06/11/24 09:19:30

  Modified:    src/org/jboss/cache/interceptors  Tag:
                        Branch_JBossCache_1_3_0
                        PessimisticLockInterceptor.java
  Log:
  Fixes to JBCACHE-875
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.14.2.2  +76 -21    JBossCache/src/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: PessimisticLockInterceptor.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/interceptors/PessimisticLockInterceptor.java,v
  retrieving revision 1.14.2.1
  retrieving revision 1.14.2.2
  diff -u -b -r1.14.2.1 -r1.14.2.2
  --- PessimisticLockInterceptor.java	23 Nov 2006 18:49:38 -0000	1.14.2.1
  +++ PessimisticLockInterceptor.java	24 Nov 2006 14:19:30 -0000	1.14.2.2
  @@ -6,25 +6,35 @@
    */
   package org.jboss.cache.interceptors;
   
  -import org.jboss.cache.*;
  +import org.jboss.cache.DataNode;
  +import org.jboss.cache.Fqn;
  +import org.jboss.cache.GlobalTransaction;
  +import org.jboss.cache.InvocationContext;
  +import org.jboss.cache.TransactionEntry;
  +import org.jboss.cache.TransactionTable;
  +import org.jboss.cache.TreeCache;
   import org.jboss.cache.lock.IdentityLock;
   import org.jboss.cache.lock.IsolationLevel;
   import org.jboss.cache.lock.LockingException;
   import org.jboss.cache.lock.TimeoutException;
   import org.jgroups.blocks.MethodCall;
   
  -import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
  -
   import javax.transaction.Transaction;
   import java.lang.reflect.Method;
  -import java.util.*;
  +import java.util.Collections;
  +import java.util.LinkedList;
  +import java.util.List;
  +import java.util.ListIterator;
  +import java.util.Map;
  +import java.util.Set;
  +import java.util.Iterator;
   
   /**
    * Handles locking. When a TX is associated, we register for TX completion and unlock the locks acquired within the
    * scope of the TX. When no TX is present, we keep track of the locks acquired during the current method and unlock
    * when the method returns
    * @author Bela Ban
  - * @version $Id: PessimisticLockInterceptor.java,v 1.14.2.1 2006/11/23 18:49:38 msurtani Exp $
  + * @version $Id: PessimisticLockInterceptor.java,v 1.14.2.2 2006/11/24 14:19:30 msurtani Exp $
    */
   public class PessimisticLockInterceptor extends Interceptor {
      TransactionTable           tx_table=null;
  @@ -32,7 +42,6 @@
      /** Map<Object, java.util.List>. Keys = threads, values = lists of locks held by that thread */
      Map                        lock_table;
      private long               lock_acquisition_timeout;
  -   Map removedNodes = new ConcurrentHashMap();
   
   
      public void setCache(TreeCache cache) {
  @@ -155,7 +164,7 @@
         // to add the removedNodes map to TreeCache
         if (storeLockedNode && ctx.getGlobalTransaction() == null)
         {
  -         removedNodes.remove(fqn);
  +         cache.getRemovedNodesMap().remove(fqn);
         }
   
         return retval;
  @@ -171,7 +180,7 @@
       * @param recursive Lock children recursively
       */
      private void lock(Fqn fqn, GlobalTransaction gtx, int lock_type, boolean recursive,
  -                     long lock_timeout, boolean createIfNotExists, boolean storeRemovalNode)
  +                     long lock_timeout, boolean createIfNotExists, boolean isRemoveNodeOperation)
            throws TimeoutException, LockingException, InterruptedException {
         DataNode       n, child_node=null;
         Object         child_name, owner=gtx != null? gtx : (Object)Thread.currentThread();
  @@ -195,19 +204,39 @@
         if(isolation_level == IsolationLevel.NONE)
            lock_type=DataNode.LOCK_TYPE_NONE;
         n=cache.getRoot();
  -      for(int i=0; i < treeNodeSize; i++) {
  -         child_name=fqn.get(i);
  +//      for(int i=0; i < treeNodeSize; i++) {
  +      for(int i=-1; i < treeNodeSize; i++) {
  +         // start with the root node - so when i==-1 we're after the root.
  +
  +         if (i == -1)
  +         {
  +            child_name = Fqn.ROOT.getName();
  +            child_node = cache.getRoot();
  +         }
  +         else
  +         {
  +            child_name = fqn.get(i);
            child_node = (DataNode) n.getChild(child_name);
  +         }
  +
            if (child_node == null)
            {
  +            if (lock_type != DataNode.LOCK_TYPE_NONE)
  +            {
               // JBCACHE-871 -- If this is a node removed by another incomplete
               // invocation or an uncommitted transaction, we won't be able to find
               // the node in the cache; so first check for it in the removedNodes map
  -            DataNode removed = (DataNode) removedNodes.get(fqn.getFqnChild(i +1));
  -            if (removed != null && lock_type != DataNode.LOCK_TYPE_NONE)
  +               DataNode removed = (DataNode) cache.getRemovedNodesMap().get(fqn.getFqnChild(i +1));
  +               if (removed != null)
               {
                  acquireNodeLock(removed, owner, gtx, lock_type, lock_timeout);
               }
  +               else
  +               {
  +                  // JBCACHE-875 - this is a create operation.  So make sure we have a WL on the PARENT.
  +                  acquireNodeLock(n, owner, gtx, DataNode.LOCK_TYPE_WRITE, lock_timeout);
  +               }
  +            }
               child_node = (DataNode) n.getOrCreateChild(child_name, gtx, createIfNotExists);
            }
   
  @@ -223,7 +252,13 @@
               continue;
            }
   
  -         if (lock_type == DataNode.LOCK_TYPE_WRITE && i == (treeNodeSize - 1))
  +         if (isRemoveNodeOperation && isTargetNode(i, treeNodeSize))
  +         {
  +            // JBCACHE-875 - this is a node removal operation.  So make sure we have a WL on the PARENT.
  +            acquireNodeLock(n, owner, gtx, DataNode.LOCK_TYPE_WRITE, lock_timeout);
  +         }
  +
  +         if (lock_type == DataNode.LOCK_TYPE_WRITE && isTargetNode(i, treeNodeSize))
            {
               currentLockType = DataNode.LOCK_TYPE_WRITE;
            }
  @@ -235,7 +270,7 @@
            // Try to acquire the lock; recording that we did if successful
            acquireNodeLock(child_node, owner, gtx, currentLockType, lock_timeout);
   
  -         if(recursive && i == (treeNodeSize - 1)) {
  +         if(recursive && isTargetNode(i, treeNodeSize)) {
               Set acquired_locks=child_node.acquireAll(owner, lock_timeout, lock_type);
               if(acquired_locks.size() > 0) {
                  if(gtx != null) {
  @@ -254,12 +289,18 @@
            n=child_node;
         }
   
  -      if (storeRemovalNode && n != null)
  +      if (isRemoveNodeOperation && n != null)
         {
  -         removedNodes.put(fqn, n);
  +         cache.getRemovedNodesMap().put(fqn, n);
  +         if (gtx != null) cache.getTransactionTable().get(gtx).addRemovedNode(fqn);
         }
      }
   
  +   private boolean isTargetNode(int nodePosition, int treeNodeSize)
  +   {
  +      return nodePosition == (treeNodeSize - 1);
  +   }
  +
      private void acquireNodeLock(DataNode node, Object owner, GlobalTransaction gtx, int lock_type, long lock_timeout) throws LockingException, TimeoutException, InterruptedException
      {
         boolean acquired = node.acquire(owner, lock_timeout, lock_type);
  @@ -331,6 +372,13 @@
            log.trace("removing local transaction " + ltx + " and global transaction " + gtx);
         tx_table.remove(ltx);
         tx_table.remove(gtx);
  +
  +      Iterator removedNodes = entry.getRemovedNodes().iterator();
  +      while (removedNodes.hasNext())
  +      {
  +         Fqn f = (Fqn) removedNodes.next();
  +         cache.getRemovedNodesMap().remove(f);
  +      }
      }
   
   
  @@ -408,6 +456,13 @@
            log.trace("removing local transaction " + ltx + " and global transaction " + tx);
         tx_table.remove(ltx);
         tx_table.remove(tx);
  +
  +      Iterator removedNodes = entry.getRemovedNodes().iterator();
  +      while (removedNodes.hasNext())
  +      {
  +         Fqn f = (Fqn) removedNodes.next();
  +         cache.getRemovedNodesMap().remove(f);
  +      }
      }
   
   }
  
  
  



More information about the jboss-cvs-commits mailing list