*/
private void lock(Fqn fqn, GlobalTransaction gtx, int lock_type, boolean recursive,
long lock_timeout, boolean createIfNotExists, boolean isRemoveNodeOperation, boolean isRemoveDataOperation)
throws TimeoutException, LockingException, InterruptedException
{
DataNode n;
DataNode child_node;
Object child_name;
Thread currentThread = Thread.currentThread();
Object owner = (gtx != null) ? (Object) gtx : currentThread;
int treeNodeSize;
int currentLockType;
if (log.isTraceEnabled()) log.trace("Attempting to lock node " + fqn + " for owner " + owner);
if (fqn == null)
{
log.error("fqn is null - this should not be the case");
return;
}
if ((treeNodeSize = fqn.size()) == 0)
return;
if (cache.getIsolationLevelClass() == IsolationLevel.NONE)
lock_type = DataNode.LOCK_TYPE_NONE;
n = cache.getRoot();
for (int i = -1; i < treeNodeSize; i++)
{
if (i == -1)
{
child_name = Fqn.ROOT.getName();
child_node = cache.getRoot();
}
else
{
child_name = fqn.get(i);
child_node = (DataNode) n.getOrCreateChild(child_name, gtx, createIfNotExists);
}
if (child_node == null)
{
if (log.isTraceEnabled())
log.trace("failed to find or create child " + child_name + " of node " + n.getFqn());
return;
}
if (lock_type == DataNode.LOCK_TYPE_NONE)
{
// acquired=false;
n = child_node;
continue;
}
else
{
if (writeLockNeeded(lock_type, i, treeNodeSize, isRemoveNodeOperation, createIfNotExists, isRemoveDataOperation, fqn, child_node.getFqn()))
{
currentLockType = DataNode.LOCK_TYPE_WRITE;
}
else
{
currentLockType = DataNode.LOCK_TYPE_READ;
}
}
// reverse the "remove" if the node has been previously removed in the same tx, if this operation is a put()
if (gtx != null && needToReverseRemove(child_node, tx_table.get(gtx), lock_type, isRemoveNodeOperation, createIfNotExists))
{
reverseRemove(child_node);
}
// Try to acquire the lock; recording that we did if successful
acquireNodeLock(child_node, owner, gtx, currentLockType, lock_timeout);
// BES 2007/12/12 -- Revert JBCACHE-1165 fix as it causes endless loop
// in TransactionTest.testDoubleNodeRemoval, plus another failure
// in that test
// // 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))
{
{
Set acquired_locks = child_node.acquireAll(owner, lock_timeout, lock_type);
if (acquired_locks.size() > 0)
{
if (gtx != null)
{
cache.getTransactionTable().addLocks(gtx, acquired_locks);