[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