Author: manik.surtani(a)jboss.com
Date: 2008-05-21 12:59:54 -0400 (Wed, 21 May 2008)
New Revision: 5882
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticTxInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java
core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java
Log:
Reorganised tx and locking methods
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java 2008-05-21
16:12:49 UTC (rev 5881)
+++
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java 2008-05-21
16:59:54 UTC (rev 5882)
@@ -13,7 +13,9 @@
import org.jboss.cache.commands.tx.CommitCommand;
import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
import org.jboss.cache.commands.tx.RollbackCommand;
+import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.lock.LockManager;
import static org.jboss.cache.lock.NodeLock.LockType.READ;
import static org.jboss.cache.lock.NodeLock.LockType.WRITE;
import org.jboss.cache.optimistic.TransactionWorkspace;
@@ -31,7 +33,14 @@
public class OptimisticLockingInterceptor extends OptimisticInterceptor
{
private long lockAcquisitionTimeout;
+ private LockManager lockManager;
+ @Inject
+ private void injectLockManager(LockManager lockManager)
+ {
+ this.lockManager = lockManager;
+ }
+
@Start
private void init()
{
@@ -134,7 +143,10 @@
try
{
TransactionEntry entry = ctx.getTransactionEntry();
- entry.releaseAllLocksFIFO(gtx);
+ if (entry != null)
+ {
+ lockManager.releaseLocks(entry.getLocks(), ctx.getGlobalTransaction());
+ }
}
catch (Exception e)
{
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticTxInterceptor.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticTxInterceptor.java 2008-05-21
16:12:49 UTC (rev 5881)
+++
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticTxInterceptor.java 2008-05-21
16:59:54 UTC (rev 5882)
@@ -7,7 +7,10 @@
import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
import org.jboss.cache.commands.tx.PrepareCommand;
import org.jboss.cache.commands.write.ClearDataCommand;
-import org.jboss.cache.commands.write.*;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
import org.jboss.cache.config.Option;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.OptimisticTransactionEntry;
@@ -139,10 +142,10 @@
@Override
protected void cleanupStaleLocks(InvocationContext ctx) throws Throwable
{
+ super.cleanupStaleLocks(ctx);
TransactionEntry entry = ctx.getTransactionEntry();
if (entry != null)
{
- entry.releaseAllLocksLIFO(ctx.getGlobalTransaction());
((OptimisticTransactionEntry) entry).getTransactionWorkSpace().clearNodes();
}
}
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2008-05-21
16:12:49 UTC (rev 5881)
+++
core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java 2008-05-21
16:59:54 UTC (rev 5882)
@@ -20,16 +20,20 @@
import org.jboss.cache.commands.tx.PrepareCommand;
import org.jboss.cache.commands.tx.RollbackCommand;
import org.jboss.cache.commands.write.ClearDataCommand;
-import org.jboss.cache.commands.write.*;
+import org.jboss.cache.commands.write.EvictCommand;
+import org.jboss.cache.commands.write.MoveCommand;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutForExternalReadCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.factories.annotations.Start;
import org.jboss.cache.interceptors.base.PostProcessingCommandInterceptor;
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.cache.lock.LockManager;
import org.jboss.cache.lock.NodeLock;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.TransactionEntry;
-import org.jboss.cache.transaction.TransactionTable;
import java.util.LinkedList;
import java.util.List;
@@ -53,25 +57,16 @@
*/
public class PessimisticLockInterceptor extends PostProcessingCommandInterceptor
{
- private TransactionTable txTable;
private DataContainerImpl dataContainer;
private LockManager lockManager;
- private long lockAcquisitionTimeout;
@Inject
- public void injectDependencies(DataContainerImpl dataContainer, TransactionTable
txTable, LockManager lockManager)
+ public void injectDependencies(DataContainerImpl dataContainer, LockManager
lockManager)
{
this.dataContainer = dataContainer;
- this.txTable = txTable;
this.lockManager = lockManager;
}
- @Start
- private void init()
- {
- lockAcquisitionTimeout = configuration.getLockAcquisitionTimeout();
- }
-
@Override
protected Object handlePutDataMapCommand(InvocationContext ctx, PutDataMapCommand
command) throws Throwable
{
@@ -125,7 +120,7 @@
// commit propagated up from the tx interceptor
commit(ctx.getTransactionEntry(), ctx.getGlobalTransaction());
Object retVal = invokeNextInterceptor(ctx, command);
- txTable.cleanup(ctx.getGlobalTransaction());
+ lockManager.releaseLocks(ctx.getTransactionEntry().getLocks(),
ctx.getGlobalTransaction());
return retVal;
}
@@ -135,7 +130,7 @@
commit(ctx.getTransactionEntry(), command.getGlobalTransaction());
if (trace) log.trace("bypassed locking as method commit() doesn't require
locking");
Object retVal = invokeNextInterceptor(ctx, command);
- txTable.cleanup(command.getGlobalTransaction());
+ lockManager.releaseLocks(ctx.getTransactionEntry().getLocks(),
ctx.getGlobalTransaction());
return retVal;
}
@@ -165,7 +160,7 @@
log.trace("bypassed locking as method rollback() doesn't require
locking");
}
Object retVal = invokeNextInterceptor(ctx, command);
- txTable.cleanup(command.getGlobalTransaction());
+ lockManager.releaseLocks(ctx.getTransactionEntry().getLocks(),
ctx.getGlobalTransaction());
return retVal;
}
@@ -173,12 +168,11 @@
protected Object handleMoveCommand(InvocationContext ctx, MoveCommand command) throws
Throwable
{
if (ctx.isLockingSuppressed()) return invokeNextInterceptor(ctx, command);
- long timeout = ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout);
// this call will ensure the node gets a WL and it's current parent gets RL.
if (trace) log.trace("Attempting to get WL on node to be moved [" +
command.getFqn() + "]");
if (command.getFqn() != null && !(configuration.getIsolationLevel() ==
IsolationLevel.NONE))
{
- lockManager.lock(ctx, command.getFqn(), NodeLock.LockType.WRITE, false, timeout,
true, false, null, false);
+ lockManager.acquireLocksWithTimeout(ctx, command.getFqn(),
NodeLock.LockType.WRITE, false, false, true, false, null, false);
if (ctx.getGlobalTransaction() != null)
{
ctx.getTransactionEntry().addRemovedNode(command.getFqn());
@@ -189,7 +183,7 @@
{
//now for an RL for the new parent.
if (trace) log.trace("Attempting to get RL on new parent [" +
command.getTo() + "]");
- lockManager.lock(ctx, command.getTo(), NodeLock.LockType.READ, false, timeout,
false, false, null, false);
+ lockManager.acquireLocksWithTimeout(ctx, command.getTo(),
NodeLock.LockType.READ, false, false, false, false, null, false);
lockManager.acquireLocksOnChildren(dataContainer.peek(command.getTo(), true,
false), NodeLock.LockType.READ, ctx);
}
Object retValue = invokeNextInterceptor(ctx, command);
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2008-05-21
16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2008-05-21
16:59:54 UTC (rev 5882)
@@ -19,12 +19,18 @@
import org.jboss.cache.commands.tx.PrepareCommand;
import org.jboss.cache.commands.tx.RollbackCommand;
import org.jboss.cache.commands.write.ClearDataCommand;
-import org.jboss.cache.commands.write.*;
+import org.jboss.cache.commands.write.CreateNodeCommand;
+import org.jboss.cache.commands.write.InvalidateCommand;
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.PutKeyValueCommand;
+import org.jboss.cache.commands.write.RemoveKeyCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
import org.jboss.cache.config.Option;
import org.jboss.cache.factories.CommandsFactory;
import org.jboss.cache.factories.ComponentRegistry;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.lock.LockManager;
import org.jboss.cache.notifications.NotifierImpl;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jboss.cache.transaction.TransactionEntry;
@@ -70,17 +76,19 @@
private long commits = 0;
private long rollbacks = 0;
protected boolean optimistic = false;
+ private LockManager lockManager;
@Inject
public void intialize(RPCManager rpcManager,
NotifierImpl notifier, InvocationContextContainer icc,
- CommandsFactory factory, ComponentRegistry componentRegistry)
+ CommandsFactory factory, ComponentRegistry componentRegistry,
LockManager lockManager)
{
this.commandsFactory = factory;
this.rpcManager = rpcManager;
this.notifier = notifier;
this.invocationContextContainer = icc;
this.componentRegistry = componentRegistry;
+ this.lockManager = lockManager;
}
@Override
@@ -592,7 +600,10 @@
protected void cleanupStaleLocks(InvocationContext ctx) throws Throwable
{
TransactionEntry entry = ctx.getTransactionEntry();
- if (entry != null) entry.releaseAllLocksLIFO(ctx.getGlobalTransaction());
+ if (entry != null)
+ {
+ lockManager.releaseLocks(entry.getLocks(), ctx.getGlobalTransaction());
+ }
}
/**
Modified: core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-21 16:12:49 UTC
(rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-05-21 16:59:54 UTC
(rev 5882)
@@ -94,8 +94,8 @@
* @param createdNodes a list to which any nodes created can register their Fqns
so that calling code is aware of which nodes have been newly created.
* @param skipNotification
*/
- public boolean lock(InvocationContext ctx, Fqn fqn, NodeLock.LockType lockType,
boolean createIfNotExists, long timeout,
- boolean acquireWriteLockOnParent, boolean reverseRemoveCheck,
List<NodeSPI> createdNodes, boolean skipNotification)
+ private boolean lock(InvocationContext ctx, Fqn fqn, NodeLock.LockType lockType,
boolean createIfNotExists, long timeout,
+ boolean acquireWriteLockOnParent, boolean reverseRemoveCheck,
List<NodeSPI> createdNodes, boolean skipNotification)
throws TimeoutException, LockingException, InterruptedException
{
Thread currentThread = Thread.currentThread();
@@ -204,7 +204,8 @@
childName = fqn.get(currentIndex);
currentNode = currentNode.getChildDirect(childName);
}
- } while (true);
+ }
+ while (true);
return created;
}
@@ -242,7 +243,7 @@
// Record the lock for release on method return or tx commit/rollback
if (gtx != null)
{
- txTable.recordNodeLock(gtx, lock);
+ ctx.getTransactionEntry().addLock(lock);
}
else
{
@@ -308,7 +309,7 @@
{
if (gtx != null)
{
- txTable.addLocks(gtx, acquiredLocks);
+ ctx.getTransactionEntry().addLocks(acquiredLocks);
if (addChildrenToDeletedList)
{
for (NodeLock l : acquiredLocks)
@@ -323,4 +324,20 @@
}
}
}
+
+ /**
+ * Releases all locks held by the owner, in reverse order of creation.
+ */
+ public void releaseLocks(List<NodeLock> locks, Object owner)
+ {
+ // Copying out to an array is faster than creating an ArrayList and iterating,
+ // since list creation will just copy out to an array internally
+ IdentityLock[] lockArray = locks.toArray(new IdentityLock[locks.size()]);
+ for (int i = lockArray.length - 1; i >= 0; i--)
+ {
+ if (trace) log.trace("releasing lock for " + lockArray[i].getFqn() +
" (" + lockArray[i] + ")");
+ lockArray[i].release(owner);
+ }
+ locks.clear();
+ }
}
Modified: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java 2008-05-21
16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java 2008-05-21
16:59:54 UTC (rev 5882)
@@ -213,53 +213,6 @@
}
/**
- * Releases all locks held by the owner, in reverse order of creation.
- * Clears the list of locks held.
- */
- public void releaseAllLocksLIFO(Object owner)
- {
-
- synchronized (locks)
- {
- // Copying out to an array is faster than creating an ArrayList and iterating,
- // since list creation will just copy out to an array internally
- IdentityLock[] lockArray = locks.toArray(new IdentityLock[locks.size()]);
- for (int i = lockArray.length - 1; i >= 0; i--)
- {
- if (trace)
- {
- log.trace("releasing lock for " + lockArray[i].getFqn() + "
(" + lockArray[i] + ")");
- }
- lockArray[i].release(owner);
- }
- locks.clear();
- }
- }
-
- /**
- * Releases all locks held by the owner, in order of creation.
- * Does not clear the list of locks held.
- */
- public void releaseAllLocksFIFO(Object owner)
- {
- // I guess a copy would work as well
- // This seems fairly safe though
- synchronized (locks)
- {
- for (NodeLock lock : locks)
- {
- lock.release(owner);
- if (trace)
- {
- log.trace("releasing lock for " + lock.getFqn() + " ("
+ lock + ")");
- }
- }
-
- locks.clear();
- }
- }
-
- /**
* Gets the value of the forceAsyncReplication flag. Used by ReplicationInterceptor
and OptimisticReplicationInterceptor
* when dealing with {@link
org.jboss.cache.Cache#putForExternalRead(org.jboss.cache.Fqn,Object,Object)} within
* a transactional context.
Modified: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java 2008-05-21
16:12:49 UTC (rev 5881)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/TransactionTable.java 2008-05-21
16:59:54 UTC (rev 5882)
@@ -15,14 +15,12 @@
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.NodeLock;
import org.jgroups.Address;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
-import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -200,45 +198,6 @@
}
/**
- * Adds a lock to the global transaction.
- */
- public void addLock(GlobalTransaction gtx, NodeLock l)
- {
- TransactionEntry entry = get(gtx);
- if (entry == null)
- {
- throw new CacheException("Unable to record lock for transaction " +
gtx + " since no transaction entry exists!");
- }
- entry.addLock(l);
- }
-
- /**
- * Adds a collection of locks to the global transaction.
- */
- public void addLocks(GlobalTransaction gtx, Collection<NodeLock> locks)
- {
- TransactionEntry entry = get(gtx);
- if (entry == null)
- {
- log.error("transaction entry not found for (globalTransaction=" + gtx
+ ")");
- return;
- }
- entry.addLocks(locks);
- }
-
- public void cleanup(GlobalTransaction gtx)
- {
- if (trace) log.trace("Cleaning up locks for globalTransaction " + gtx);
- TransactionEntry entry = this.get(gtx);
- // Let's do it in stack style, LIFO
- if (entry != null)
- entry.releaseAllLocksLIFO(gtx);
- else
- log.error("No transaction entry present!!");
- }
-
-
- /**
* Returns summary debug information.
*/
@Override
@@ -274,24 +233,6 @@
}
/**
- * Add the lock to the list of locks maintained for this transaction
- * (needed for release of locks on commit or rollback)
- */
- public void recordNodeLock(GlobalTransaction gtx, NodeLock lock)
- {
- try
- {
- addLock(gtx, lock);
- }
- catch (CacheException e)
- {
- // may happen, if the transaction entry does not exist
- lock.release(gtx);
- throw e;
- }
- }
-
- /**
* Returns the transaction associated with the current thread.
* If a local transaction exists, but doesn't yet have a mapping to a
* GlobalTransaction, a new GlobalTransaction will be created and mapped to