[infinispan-commits] Infinispan SVN: r2372 - in branches/4.2.x: core/src/main/java/org/infinispan/affinity and 13 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Tue Sep 14 20:16:20 EDT 2010
Author: mircea.markus
Date: 2010-09-14 20:16:18 -0400 (Tue, 14 Sep 2010)
New Revision: 2372
Added:
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java
Removed:
branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DistDldGlobalTransaction.java
branches/4.2.x/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java
branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java
Modified:
branches/4.2.x/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java
branches/4.2.x/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java
branches/4.2.x/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java
branches/4.2.x/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java
branches/4.2.x/core/src/main/java/org/infinispan/context/InvocationContext.java
branches/4.2.x/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java
branches/4.2.x/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java
branches/4.2.x/core/src/main/java/org/infinispan/marshall/Ids.java
branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java
branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java
branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java
branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java
branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java
branches/4.2.x/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java
branches/4.2.x/pom.xml
Log:
[ISPN-631] - DLD and dist tests are disabled - enable and enhance these tests
Modified: branches/4.2.x/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -94,6 +94,8 @@
if (!started) {
throw new IllegalStateException("You have to start the service first!");
}
+ if (address == null)
+ throw new NullPointerException("Null address not supported!");
BlockingQueue queue = address2key.get(address);
try {
maxNumberInvariant.readLock().lock();
Modified: branches/4.2.x/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -59,7 +59,9 @@
import org.infinispan.interceptors.InterceptorChain;
import org.infinispan.notifications.cachelistener.CacheNotifier;
import org.infinispan.remoting.transport.Address;
+import org.infinispan.transaction.xa.DldGlobalTransaction;
import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.transaction.xa.RemoteTransaction;
import org.infinispan.transaction.xa.TransactionTable;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
@@ -67,6 +69,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* @author Mircea.Markus at jboss.com
@@ -256,8 +259,14 @@
pc.init(interceptorChain, icc, txTable);
pc.initialize(notifier);
if (pc.getModifications() != null)
- for (ReplicableCommand nested : pc.getModifications()) initializeReplicableCommand(nested, false);
+ for (ReplicableCommand nested : pc.getModifications()) {
+ initializeReplicableCommand(nested, false);
+ }
pc.markTransactionAsRemote(isRemote);
+ if (configuration.isEnableDeadlockDetection() && isRemote) {
+ DldGlobalTransaction transaction = (DldGlobalTransaction) pc.getGlobalTransaction();
+ transaction.setLocksHeldAtOrigin(pc.getAffectedKeys());
+ }
break;
case CommitCommand.COMMAND_ID:
CommitCommand commitCommand = (CommitCommand) c;
@@ -281,6 +290,21 @@
LockControlCommand lcc = (LockControlCommand) c;
lcc.init(interceptorChain, icc, txTable);
lcc.markTransactionAsRemote(isRemote);
+ if (configuration.isEnableDeadlockDetection() && isRemote) {
+ DldGlobalTransaction gtx = (DldGlobalTransaction) lcc.getGlobalTransaction();
+ RemoteTransaction transaction = txTable.getRemoteTransaction(gtx);
+ if (transaction != null) {
+ if (!configuration.getCacheMode().isDistributed()) {
+ Set<Object> keys = txTable.getLockedKeysForRemoteTransaction(gtx);
+ GlobalTransaction gtx2 = transaction.getGlobalTransaction();
+ ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(keys);
+ gtx.setLocksHeldAtOrigin(keys);
+ } else {
+ GlobalTransaction gtx2 = transaction.getGlobalTransaction();
+ ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(gtx.getLocksHeldAtOrigin());
+ }
+ }
+ }
break;
case RehashControlCommand.COMMAND_ID:
RehashControlCommand rcc = (RehashControlCommand) c;
Modified: branches/4.2.x/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -48,7 +48,6 @@
*
* @author Vladimir Blagojevic (<a href="mailto:vblagoje at redhat.com">vblagoje at redhat.com</a>)
* @author Mircea.Markus at jboss.com
- * @param
* @since 4.0
*/
@Marshallable(externalizer = ReplicableCommandExternalizer.class, id = Ids.LOCK_CONTROL_COMMAND)
Modified: branches/4.2.x/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -105,7 +105,7 @@
ctx.setRemoteTransaction(remoteTransaction);
if (trace)
- log.trace("Invoking remotly orginated prepare: " + this);
+ log.trace("Invoking remotely originated prepare: " + this + " with invocation context: " + ctx);
notifier.notifyTransactionRegistered(ctx.getGlobalTransaction(), ctx);
try {
return invoker.invoke(ctx, this);
Modified: branches/4.2.x/core/src/main/java/org/infinispan/context/InvocationContext.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/context/InvocationContext.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/context/InvocationContext.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -48,15 +48,15 @@
*/
Object getLockOwner();
- /**
- * Returns true if the context has any locked entries associated with it.
- */
- boolean hasLockedEntries();
-
boolean isUseFutureReturnType();
void setUseFutureReturnType(boolean useFutureReturnType);
InvocationContext clone();
+ /**
+ * Returns the set of keys that are locked for writing.
+ */
+ public Set getLockedKeys();
+
}
Modified: branches/4.2.x/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -3,11 +3,11 @@
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
-import org.infinispan.util.BidirectionalMap;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
+import java.util.HashSet;
import java.util.Set;
/**
@@ -123,18 +123,7 @@
}
}
- public boolean hasLockedEntries() {
- BidirectionalMap<Object, CacheEntry> lookedUpEntries = getLookedUpEntries();
- boolean result = false;
- for (CacheEntry e : lookedUpEntries.values()) {
- if (e.isChanged()) {
- result = true;
- }
- }
- return result;
- }
-
public boolean isUseFutureReturnType() {
return isContextFlagSet(ContextFlag.USE_FUTURE_RETURN_TYPE);
}
@@ -154,6 +143,15 @@
}
}
+ public Set getLockedKeys() {
+ Set result = new HashSet();
+ for (Object key : getLookedUpEntries().keySet()) {
+ if (hasLockedKey(key))
+ result.add(key);
+ }
+ return result;
+ }
+
@Override
public String toString() {
return getClass().getSimpleName() + "{" +
Modified: branches/4.2.x/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -12,12 +12,12 @@
import org.infinispan.factories.annotations.Start;
import org.infinispan.interceptors.base.CommandInterceptor;
import org.infinispan.transaction.xa.DldGlobalTransaction;
-import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
-import org.infinispan.util.concurrent.locks.LockManager;
+import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.transaction.xa.RemoteTransaction;
+import org.infinispan.transaction.xa.TransactionTable;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
import java.util.Collections;
+import java.util.Set;
/**
* This interceptor populates the {@link org.infinispan.transaction.xa.DldGlobalTransaction} with
@@ -32,15 +32,6 @@
*/
public class DeadlockDetectingInterceptor extends CommandInterceptor {
- private LockManager lockManager;
- private TransactionManager txManager;
-
- @Inject
- public void init(LockManager lockManager, TransactionManager txManager) {
- this.lockManager = lockManager;
- this.txManager = txManager;
- }
-
/**
* Only does a sanity check.
*/
@@ -71,7 +62,12 @@
DldGlobalTransaction globalTransaction = (DldGlobalTransaction) ctx.getGlobalTransaction();
if (ctx.isOriginLocal()) {
globalTransaction.setRemoteLockIntention(command.getKeys());
- }
+ //in the case of DIST we need to propagate the list of keys. In all other situations in can be determined
+ // based on the actual command
+ if (configuration.getCacheMode().isDistributed()) {
+ ((DldGlobalTransaction) ctx.getGlobalTransaction()).setLocksHeldAtOrigin(ctx.getLockedKeys());
+ }
+ }
return handleDataCommand(ctx, command);
}
Modified: branches/4.2.x/core/src/main/java/org/infinispan/marshall/Ids.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/marshall/Ids.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/marshall/Ids.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -117,7 +117,4 @@
static final byte BYTE_ARRAY_KEY = 57;
static final byte TOPOLOGY_ADDRESS = 58;
static final byte TOPOLOGY_VIEW = 59;
-
- //added in 4.2
- static final byte LOCK_INTENTION_NOTIFICATION_COMMAND = 60;
}
Deleted: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DistDldGlobalTransaction.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DistDldGlobalTransaction.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DistDldGlobalTransaction.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,35 +0,0 @@
-package org.infinispan.transaction.xa;
-
-import org.infinispan.distribution.DistributionManager;
-import org.infinispan.remoting.transport.Address;
-
-/**
- * @author Mircea.Markus at jboss.com
- * @since 4.1
- */
-public class DistDldGlobalTransaction extends DldGlobalTransaction {
-
- private volatile DistributionManager distManager;
- private volatile int numOwners;
-
- public DistDldGlobalTransaction(DistributionManager distManager, int numOwners) {
- this.distManager = distManager;
- this.numOwners = numOwners;
- }
-
- public DistDldGlobalTransaction(Address addr, boolean remote, DistributionManager distManager, int numOwners) {
- super(addr, remote);
- this.distManager = distManager;
- this.numOwners = numOwners;
- }
-
- @Override
- public boolean isAcquiringRemoteLock(Object key, Address address) {
- boolean affectsKey = remoteLockIntention.contains(key);
- if (affectsKey) {
- return distManager.getConsistentHash().isKeyLocalToAddress(address, key, numOwners);
- } else {
- return false;
- }
- }
-}
Modified: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -28,10 +28,11 @@
private volatile boolean isMarkedForRollback;
- private transient volatile Object lockLocalLockIntention;
+ private transient volatile Object localLockIntention;
protected volatile Set<Object> remoteLockIntention = Collections.EMPTY_SET;
+ private volatile Set<Object> locksAtOrigin = Collections.EMPTY_SET;
public DldGlobalTransaction() {
}
@@ -76,8 +77,9 @@
return "DldGlobalTransaction{" +
"coinToss=" + coinToss +
", isMarkedForRollback=" + isMarkedForRollback +
- ", lockIntention=" + lockLocalLockIntention +
+ ", lockIntention=" + localLockIntention +
", affectedKeys=" + remoteLockIntention +
+ ", locksAtOrigin=" + locksAtOrigin +
"} " + super.toString();
}
@@ -93,11 +95,11 @@
* Returns the key this transaction intends to lock.
*/
public Object getLockIntention() {
- return lockLocalLockIntention;
+ return localLockIntention;
}
- public void setLockLocalLockIntention(Object lockIntention) {
- this.lockLocalLockIntention = lockIntention;
+ public void setLockIntention(Object lockIntention) {
+ this.localLockIntention = lockIntention;
}
public boolean wouldLose(DldGlobalTransaction other) {
@@ -112,7 +114,7 @@
public void setRemoteLockIntention(Set<Object> remoteLockIntention) {
if (trace) {
- log.trace("Setting the affected keys set to: " + remoteLockIntention);
+ log.trace("Setting the remote lock intention: " + remoteLockIntention);
}
this.remoteLockIntention = remoteLockIntention;
}
@@ -121,6 +123,25 @@
return remoteLockIntention;
}
+ public boolean hasLockAtOrigin(Set<Object> remoteLockIntention) {
+ if (log.isTraceEnabled()) log.trace("Our(" + this + ") locks at origin are: " + locksAtOrigin + ". Others remote lock intention is: " + remoteLockIntention);
+ for (Object key : remoteLockIntention) {
+ if (this.locksAtOrigin.contains(key)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setLocksHeldAtOrigin(Set<Object> locksAtOrigin) {
+ if (trace) log.trace("Setting locks at origin for (" + this + ") to " + locksAtOrigin);
+ this.locksAtOrigin = locksAtOrigin;
+ }
+
+ public Set<Object> getLocksHeldAtOrigin() {
+ return this.locksAtOrigin;
+ }
+
public static class Externalizer extends GlobalTransaction.Externalizer {
public Externalizer() {
gtxFactory = new GlobalTransactionFactory(true);
@@ -131,12 +152,23 @@
super.writeObject(output, subject);
DldGlobalTransaction ddGt = (DldGlobalTransaction) subject;
output.writeLong(ddGt.getCoinToss());
+ if (ddGt.locksAtOrigin.isEmpty()) {
+ output.writeObject(null);
+ } else {
+ output.writeObject(ddGt.locksAtOrigin);
+ }
}
@Override
public Object readObject(ObjectInput input) throws IOException, ClassNotFoundException {
DldGlobalTransaction ddGt = (DldGlobalTransaction) super.readObject(input);
ddGt.setCoinToss(input.readLong());
+ Object locksAtOriginObj = input.readObject();
+ if (locksAtOriginObj == null) {
+ ddGt.setLocksHeldAtOrigin(Collections.EMPTY_SET);
+ } else {
+ ddGt.setLocksHeldAtOrigin((Set<Object>) locksAtOriginObj);
+ }
return ddGt;
}
}
Modified: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -64,17 +64,12 @@
GlobalTransaction gtx;
if (isEddEnabled) {
DldGlobalTransaction globalTransaction;
- if (configuration.getCacheMode().isDistributed()) {
- globalTransaction = new DistDldGlobalTransaction(addr, remote, distributionManager, configuration.getNumOwners());
- } else {
- globalTransaction = new DldGlobalTransaction(addr, remote);
- }
+ globalTransaction = new DldGlobalTransaction(addr, remote);
globalTransaction.setCoinToss(generateRandomId());
gtx = globalTransaction;
} else {
gtx = new GlobalTransaction(addr, remote);
}
-
return gtx;
}
}
Modified: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -4,11 +4,15 @@
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.util.BidirectionalLinkedHashMap;
import org.infinispan.util.BidirectionalMap;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
/**
* Defines the state of a remotely originated transaction.
@@ -18,6 +22,8 @@
*/
public class RemoteTransaction implements CacheTransaction, Cloneable {
+ private static Log log = LogFactory.getLog(RemoteTransaction.class);
+
private List<WriteCommand> modifications;
private BidirectionalLinkedHashMap<Object, CacheEntry> lookedUpEntries;
@@ -58,6 +64,9 @@
}
public void putLookedUpEntry(Object key, CacheEntry e) {
+ if (log.isTraceEnabled()) {
+ log.trace("Adding key " + key + " to tx " + getGlobalTransaction());
+ }
lookedUpEntries.put(key, e);
}
@@ -103,4 +112,14 @@
", tx=" + tx +
'}';
}
+
+ public Set<Object> getLockedKeys() {
+ Set<Object> result = new HashSet<Object>();
+ for (Object key : getLookedUpEntries().keySet()) {
+ result.add(key);
+ }
+ if (lookedUpEntries.entrySet().size() != result.size())
+ throw new IllegalStateException("Different sizes!");
+ return result;
+ }
}
Modified: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -23,7 +23,7 @@
import org.infinispan.util.logging.LogFactory;
import javax.transaction.Transaction;
-import java.util.HashMap;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -83,6 +83,12 @@
lockBreakingService.shutdownNow();
}
+ public Set<Object> getLockedKeysForRemoteTransaction(GlobalTransaction gtx) {
+ RemoteTransaction transaction = remoteTransactions.get(gtx);
+ if (transaction == null) return Collections.EMPTY_SET;
+ return transaction.getLockedKeys();
+ }
+
@Listener
public class StaleTransactionCleanup {
@ViewChanged
Modified: branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -6,7 +6,6 @@
import org.infinispan.jmx.annotations.ManagedAttribute;
import org.infinispan.jmx.annotations.ManagedOperation;
import org.infinispan.transaction.xa.DldGlobalTransaction;
-import org.infinispan.transaction.xa.TransactionTable;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import org.rhq.helpers.pluginAnnotations.agent.MeasurementType;
@@ -62,12 +61,12 @@
if (trace) log.trace("Using early dead lock detection");
final long start = System.currentTimeMillis();
DldGlobalTransaction thisTx = (DldGlobalTransaction) ctx.getLockOwner();
- thisTx.setLockLocalLockIntention(key);
+ thisTx.setLockIntention(key);
if (trace) log.trace("Setting lock intention to: " + key);
while (System.currentTimeMillis() < (start + lockTimeout)) {
if (lockContainer.acquireLock(key, spinDuration, MILLISECONDS) != null) {
- thisTx.setLockLocalLockIntention(null); //clear lock intention
+ thisTx.setLockIntention(null); //clear lock intention
if (trace) log.trace("successfully acquired lock on " + key + ", returning ...");
return true;
} else {
@@ -112,26 +111,21 @@
private boolean ownsRemoteIntention(DldGlobalTransaction lockOwnerTx, DldGlobalTransaction thisTx, Object key) {
if (!lockOwnerTx.isRemote()) {
// I've already acquired lock on this key before replicating here, so this mean we are in deadlock. This assumes the fact that
- // if trying to acquire a remote lock, a tx first acquires a local lock. This stands true in all situations but
- // when DLD + eager locking is used (in this scenario remote locks are acquired first).
- if (lockOwnerTx.isAcquiringRemoteLock(key, thisTx.getAddress())) {
+ // if trying to acquire a remote lock, a tx first acquires a local lock.
+ if (thisTx.hasLockAtOrigin(lockOwnerTx.getRemoteLockIntention())) {
if (trace)
log.trace("Same key deadlock detected: lock owner tries to acquire lock remotely on " + key + " but we have it!");
return true;
}
- for (Object remoteIntention : lockOwnerTx.getRemoteLockIntention()) {
- if (ownsLock(remoteIntention, thisTx)) {
- if (trace) log.trace("We own lock on a key ('" + remoteIntention + "') on which other tx wants to acquire remote lock");
- return true;
- }
- }
+ } else {
+ if (trace) log.trace("Lock owner is remote: " + lockOwnerTx);
}
return false;
}
- private boolean ownsLocalIntention(DldGlobalTransaction tx, Object intention) {
- boolean result = intention != null && ownsLock(intention, tx);
- if (trace) log.trace("Intention is '" + intention + "'. Do we own lock for it? " + result + " We == " + tx);
+ private boolean ownsLocalIntention(DldGlobalTransaction thisTx, Object intention) {
+ boolean result = intention != null && ownsLock(intention, thisTx);
+ if (trace) log.trace("Local intention is '" + intention + "'. Do we own lock for it? " + result + " We == " + thisTx);
return result;
}
Deleted: branches/4.2.x/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,42 +0,0 @@
-package org.infinispan.distribution;
-
-import org.infinispan.config.Configuration;
-import org.infinispan.tx.ReplDeadlockDetectionTest;
-import static org.testng.Assert.fail;
-import org.testng.annotations.Test;
-
-/**
- * Test deadlock detection when cache is configured for distribution.
- *
- * @author Mircea.Markus at jboss.com
- */
- at Test(groups = "functional", testName = "distribution.DeadlockDetectionDistributionTest")
-public class DeadlockDetectionDistributionTest extends ReplDeadlockDetectionTest {
-
-// public DeadlockDetectionDistributionTest() {
-// cacheMode = Configuration.CacheMode.DIST_SYNC;
-// }
-//
-//
-// public void testDeadlockDetectedTwoTransactions() throws Exception {
-// fail("This test should be updated to make sure tx replicate on opposite nodes");
-// }
-//
-//
-// //following methods are overridden as TestNG will otherwise run them even if I mark the class as enabled = false
-//
-// @Override
-// public void testExpectedInnerStructure() {
-// throw new IllegalStateException("TODO - please implement me!!!"); //todo implement!!!
-// }
-//
-// @Override
-// public void testDeadlockDetectedOneTx() throws Exception {
-// throw new IllegalStateException("TODO - please implement me!!!"); //todo implement!!!
-// }
-//
-// @Override
-// public void testLockReleasedWhileTryingToAcquire() throws Exception {
-// throw new IllegalStateException("TODO - please implement me!!!"); //todo implement!!!
-// }
-}
Deleted: branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,186 +0,0 @@
-package org.infinispan.tx;
-
-import org.infinispan.Cache;
-import org.infinispan.commands.VisitableCommand;
-import org.infinispan.commands.write.PutKeyValueCommand;
-import org.infinispan.config.Configuration;
-import org.infinispan.context.InvocationContext;
-import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.test.PerCacheExecutorThread;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.xa.TransactionTable;
-import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
-import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
-import org.infinispan.util.concurrent.locks.LockManager;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-/**
- * Tests deadlock detection for async caches.
- *
- * @author Mircea.Markus at jboss.com
- */
- at Test(groups = "functional", testName = "tx.AsyncDeadlockDetectionTest")
-public class AsyncDeadlockDetectionTest extends MultipleCacheManagersTest {
- private PerCacheExecutorThread t0;
- private PerCacheExecutorThread t1;
- private RemoteReplicationInterceptor remoteReplicationInterceptor;
-
-
- protected void createCacheManagers() throws Throwable {
- Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC, true);
- config.setEnableDeadlockDetection(true);
- config.setSyncCommitPhase(true);
- config.setSyncRollbackPhase(true);
- config.setUseLockStriping(false);
- assert config.isEnableDeadlockDetection();
- createClusteredCaches(2, "test", config);
- assert config.isEnableDeadlockDetection();
-
-
- remoteReplicationInterceptor = new RemoteReplicationInterceptor();
- Cache cache0 = cache(0, "test");
- Cache cache1 = cache(1, "test");
- cache1.getAdvancedCache().addInterceptor(remoteReplicationInterceptor, 0);
- assert cache0.getConfiguration().isEnableDeadlockDetection();
- assert cache1.getConfiguration().isEnableDeadlockDetection();
- assert !cache0.getConfiguration().isExposeJmxStatistics();
- assert !cache1.getConfiguration().isExposeJmxStatistics();
-
- ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0)).setExposeJmxStats(true);
- ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1)).setExposeJmxStats(true);
- }
-
- @BeforeMethod
- public void beforeMethod() {
- Cache cache0 = cache(0, "test");
- Cache cache1 = cache(1, "test");
- t0 = new PerCacheExecutorThread(cache0, 0);
- t1 = new PerCacheExecutorThread(cache1, 1);
- }
-
- @AfterMethod
- public void afterMethod() {
- Cache cache0 = cache(0, "test");
- Cache cache1 = cache(1, "test");
- t0.stopThread();
- t1.stopThread();
- ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0)).resetStatistics();
- ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1)).resetStatistics();
- remoteReplicationInterceptor.executionResponse = null;
- remoteReplicationInterceptor = null;
- t0 = null;
- t1 = null;
- }
-
- public void testRemoteTxVsLocal() throws Exception {
- Cache cache0 = cache(0, "test");
- Cache cache1 = cache(1, "test");
- assertEquals(PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK, t0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX));
- t0.setKeyValue("k1", "v1_t0");
- assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
- t0.setKeyValue("k2", "v2_t0");
- assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
-
- assertEquals(PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK, t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX));
- t1.setKeyValue("k2", "v2_t1");
- assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
-
- t0.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
-
- final LockManager lm1 = TestingUtil.extractLockManager(cache1);
-
- eventually(new Condition() {
- public boolean isSatisfied() throws Exception {
- return lm1.isLocked("k1");
- }
- }); //now t0 replicated, acquired lock on k1 and it tries to acquire lock on k2
-
-
- t1.setKeyValue("k1", "v1_t1");
- t1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-
-
- Object t1Response = t1.waitForResponse();
- Object t0Response = remoteReplicationInterceptor.getResponse();
-
- log.trace("t0Response = " + t0Response);
- log.trace("t1Response = " + t1Response);
-
- assert xor(t1Response instanceof DeadlockDetectedException, t0Response instanceof DeadlockDetectedException);
- TransactionTable transactionTable1 = TestingUtil.extractComponent(cache1, TransactionTable.class);
-
-
- if (t0Response instanceof DeadlockDetectedException) {
- replListener(cache0).expectWithTx(PutKeyValueCommand.class, PutKeyValueCommand.class);
- assertEquals(t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX), PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK);
- replListener(cache0).waitForRpc();
- assertEquals(transactionTable1.getLocalTxCount(), 0);
- }
-
- DeadlockDetectingLockManager ddLm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0);
- DeadlockDetectingLockManager ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1);
-
- assertFalse(ddLm0.isLocked("k1"));
- assertFalse(ddLm1.isLocked("k1"));
- assertFalse(ddLm0.isLocked("k2"));
- assertFalse(ddLm1.isLocked("k2"));
- TransactionTable transactionTable0 = TestingUtil.extractComponent(cache0, TransactionTable.class);
- assertEquals(transactionTable0.getLocalTxCount(), 0);
- for (int i = 0; i < 20; i++) {
- if (!(transactionTable0.getRemoteTxCount() == 0)) Thread.sleep(50);
- }
-
- assertEquals(transactionTable0.getRemoteTxCount(), 0);
-
- for (int i = 0; i < 20; i++) {
- if (!(transactionTable1.getRemoteTxCount() == 0)) Thread.sleep(50);
- }
- assertEquals(transactionTable1.getRemoteTxCount(), 0);
-
- if (t1Response instanceof DeadlockDetectedException) {
- assertEquals(cache0.get("k1"), "v1_t0");
- assertEquals(cache0.get("k2"), "v2_t0");
- assertEquals(cache1.get("k1"), "v1_t0");
- assertEquals(cache1.get("k2"), "v2_t0");
- } else {
- assertEquals(cache0.get("k1"), "v1_t1");
- assertEquals(cache0.get("k2"), "v2_t1");
- assertEquals(cache1.get("k1"), "v1_t1");
- assertEquals(cache1.get("k2"), "v2_t1");
- }
- }
-
-
- public static class RemoteReplicationInterceptor extends CommandInterceptor {
-
- public volatile Object executionResponse;
-
- @Override
- protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
- try {
- return invokeNextInterceptor(ctx, command);
- } catch (Throwable throwable) {
- if (!ctx.isOriginLocal()) {
- log.trace("Setting executionResponse to " + throwable);
- executionResponse = throwable;
- } else {
- log.trace("Ignoring throwable " + throwable);
- executionResponse = "NONE";
- }
- throw throwable;
- }
- }
-
- public Object getResponse() throws Exception {
- while (executionResponse == null) {
- Thread.sleep(50);
- }
- return executionResponse;
- }
- }
-}
Deleted: branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,128 +0,0 @@
-package org.infinispan.tx;
-
-import org.infinispan.config.Configuration;
-import org.infinispan.context.Flag;
-import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.test.PerCacheExecutorThread;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.util.concurrent.TimeoutException;
-import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
-import org.infinispan.util.concurrent.locks.containers.LockContainer;
-import org.testng.annotations.Test;
-
-import javax.transaction.Status;
-import javax.transaction.TransactionManager;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author Mircea.Markus at jboss.com
- * @since 4.1
- */
- at Test(groups = "functional", testName = "tx.EagerTxDeadlockDetectionTest")
-public class EagerTxDeadlockDetectionTest extends MultipleCacheManagersTest {
- private PerCacheExecutorThread ex1;
- private PerCacheExecutorThread ex2;
- private DeadlockDetectingLockManager lm0;
- private DeadlockDetectingLockManager lm1;
-
- @Override
- protected void createCacheManagers() throws Throwable {
- Configuration configuration = getConfiguration();
- createClusteredCaches(2, configuration);
- ex1 = new PerCacheExecutorThread(cache(0), 1);
- ex2 = new PerCacheExecutorThread(cache(1), 2);
- lm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0));
- lm0.setExposeJmxStats(true);
- lm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1));
- lm1.setExposeJmxStats(true);
- }
-
- protected Configuration getConfiguration() throws Exception {
- Configuration configuration = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
- configuration.setUseEagerLocking(true);
- configuration.setEnableDeadlockDetection(true);
- configuration.setUseLockStriping(false);
- return configuration;
- }
-
- public void testDeadlock() throws Exception {
- long start = System.currentTimeMillis();
- ex1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
- ex2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
-
- ex1.setKeyValue("k1", "v1_1");
- ex1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- ex2.setKeyValue("k2", "v2_2");
- ex2.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- assert lm0.isLocked("k1");
- assert lm0.isLocked("k2");
- assert lm1.isLocked("k1");
- assert lm1.isLocked("k2");
-
- log.trace("After first set of puts");
-
- ex1.clearResponse();
- ex2.clearResponse();
-
- log.info("Here is where DLD happens");
-
- ex2.setKeyValue("k1", "v1_2");
- ex2.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- ex1.setKeyValue("k2", "v2_1");
- ex1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- ex1.waitForResponse();
- ex2.waitForResponse();
-
-
- boolean b1 = ex1.lastResponse() instanceof Exception;
- boolean b2 = ex2.lastResponse() instanceof Exception;
- log.info("b1:", b1);
- log.info("b2:", b2);
- assert xor(b1, b2) : "Both are " + (b1 || b2);
-
- assert xor(ex1.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK,
- ex2.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK);
-
-
- ex1.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
- ex2.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
-
-
- assert cache(0).get("k1") != null;
- assert cache(0).get("k2") != null;
- assert cache(1).get("k1") != null;
- assert cache(1).get("k2") != null;
-
- long totalDeadlocks = lm0.getTotalNumberOfDetectedDeadlocks() + lm1.getTotalNumberOfDetectedDeadlocks();
- assert totalDeadlocks == 1 : "Expected 1 but received " + totalDeadlocks;
-
- System.out.println("Test took " + (System.currentTimeMillis() - start) + " millis.");
- }
-
- /**
- * On eager locking, remote locks are being acquired at first, and then local locks. This is for specifying the
- * behavior whe remote acquisition succeeds and local fails.
- */
- public void testDeadlockFailedToAcquireLocalLocks() throws Exception {
- //first acquire a local lock on k1
- TransactionManager tm = TestingUtil.getTransactionManager(cache(0));
- tm.begin();
- cache(0).getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL).put("k1","v1");
- assert lm0.isLocked("k1");
- assert !lm1.isLocked("k1");
-
- try {
- ex1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
- ex1.setKeyValue("k1", "v1_1");
- ex1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- assert ex1.lastResponse() instanceof TimeoutException;
- eventually(new Condition() {
- public boolean isSatisfied() throws Exception {
- return !lm1.isLocked("k1");
- }
- });
- } finally {
- tm.rollback();
- }
- }
-}
Deleted: branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,190 +0,0 @@
-package org.infinispan.tx;
-
-import org.infinispan.config.Configuration;
-import org.infinispan.manager.EmbeddedCacheManager;
-import org.infinispan.test.PerCacheExecutorThread;
-import org.infinispan.test.SingleCacheManagerTest;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
-import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
-import static org.testng.Assert.assertEquals;
-
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.RollbackException;
-
-/**
- * Tests deadlock detection functionality for local caches.
- *
- * @author Mircea.Markus at jboss.com
- */
- at Test(groups = "functional", testName = "tx.LocalDeadlockDetectionTest")
-public class LocalDeadlockDetectionTest extends SingleCacheManagerTest {
-
- private PerCacheExecutorThread t1;
- private PerCacheExecutorThread t2;
- private DeadlockDetectingLockManager lockManager;
- private Object response1;
- private Object response2;
-
- protected EmbeddedCacheManager createCacheManager() throws Exception {
- cacheManager = TestCacheManagerFactory.createLocalCacheManager();
- Configuration configuration = getDefaultStandaloneConfig(true);
- configuration.setEnableDeadlockDetection(true);
- configuration.setUseLockStriping(false);
- configuration.setExposeJmxStatistics(true);
- cacheManager.defineConfiguration("test", configuration);
- cache = cacheManager.getCache("test");
- lockManager = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache);
- return cacheManager;
- }
-
- @BeforeMethod
- public void startExecutors() {
- t1 = new PerCacheExecutorThread(cache, 0);
- t2 = new PerCacheExecutorThread(cache, 1);
- lockManager.resetStatistics();
- }
-
-
- @AfterMethod
- public void stopExecutors() {
- t1.stopThread();
- t2.stopThread();
- }
-
- public void testDldPutAndPut() {
- testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
- PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- if (response1 instanceof Exception) {
- assertEquals("value_1_t2", cache.get("k1"));
- assertEquals("value_2_t2", cache.get("k2"));
- } else {
- assertEquals("value_1_t1", cache.get("k1"));
- assertEquals("value_2_t1", cache.get("k2"));
- }
- }
-
- public void testDldPutAndRemove() {
- testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
- PerCacheExecutorThread.Operations.REMOVE_KEY);
- if (response1 instanceof Exception) {
- assertEquals(cache.get("k1"), null);
- assertEquals("value_2_t2", cache.get("k2"));
- } else {
- assertEquals("value_1_t1", cache.get("k1"));
- assertEquals(null, cache.get("k2"));
- }
- }
-
- public void testDldRemoveAndPut() {
- testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REMOVE_KEY,
- PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- if (response1 instanceof Exception) {
- System.out.println("t1 failure");
- assertEquals(cache.get("k1"), "value_1_t2");
- assertEquals(cache.get("k2"), null);
- } else {
- System.out.println("t2 failure");
- assertEquals(cache.get("k1"), null);
- assertEquals(cache.get("k2"), "value_2_t1");
- }
- }
-
- public void testDldRemoveAndRemove() {
- testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REMOVE_KEY,
- PerCacheExecutorThread.Operations.REMOVE_KEY);
- if (response1 instanceof Exception) {
- System.out.println("t1 failure");
- assertEquals(cache.get("k1"), null);
- assertEquals(cache.get("k2"), null);
- } else {
- System.out.println("t2 failure");
- assertEquals(cache.get("k1"), null);
- assertEquals(cache.get("k2"), null);
- }
- }
-
- public void testDldPutAndReplace() {
-
- cache.put("k1", "initial_1");
- cache.put("k2", "initial_2");
-
- testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
- PerCacheExecutorThread.Operations.REPLACE_KEY_VALUE);
- if (response1 instanceof Exception) {
- System.out.println("t1 failure");
- assertEquals(cache.get("k1"), "value_1_t2");
- assertEquals(cache.get("k2"), "value_2_t2");
- } else {
- System.out.println("t2 failure");
- assertEquals(cache.get("k1"), "value_1_t1");
- assertEquals(cache.get("k2"), "value_2_t1");
- }
- }
-
- public void testDldReplaceAndPut() {
-
- cache.put("k1", "initial_1");
- cache.put("k2", "initial_2");
-
- testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REPLACE_KEY_VALUE,
- PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- if (response1 instanceof Exception) {
- System.out.println("t1 failure");
- assertEquals(cache.get("k1"), "value_1_t2");
- assertEquals(cache.get("k2"), "value_2_t2");
- } else {
- System.out.println("t2 failure");
- assertEquals(cache.get("k1"), "value_1_t1");
- assertEquals(cache.get("k2"), "value_2_t1");
- }
- }
-
-
- private void testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations firstOperation, PerCacheExecutorThread.Operations secondOperation) {
-
- assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
- assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
- System.out.println("After begin");
-
- t1.setKeyValue("k1", "value_1_t1");
- t2.setKeyValue("k2", "value_2_t2");
-
- assertEquals(t1.execute(firstOperation), firstOperation.getCorrespondingOkResult());
- assertEquals(t2.execute(firstOperation), firstOperation.getCorrespondingOkResult());
-
- assert lockManager.isLocked("k1");
- assert lockManager.isLocked("k2");
-
-
- t1.setKeyValue("k2", "value_2_t1");
- t2.setKeyValue("k1", "value_1_t2");
- t1.executeNoResponse(secondOperation);
- t2.executeNoResponse(secondOperation);
-
- response1 = t1.waitForResponse();
- response2 = t2.waitForResponse();
-
- assert xor(response1 instanceof DeadlockDetectedException, response2 instanceof DeadlockDetectedException) : "expected one and only one exception: " + response1 + ", " + response2;
- assert xor(response1 == secondOperation.getCorrespondingOkResult(), response2 == secondOperation.getCorrespondingOkResult()) : "expected one and only one exception: " + response1 + ", " + response2;
-
- assert lockManager.isLocked("k1");
- assert lockManager.isLocked("k2");
- assert lockManager.getOwner("k1") == lockManager.getOwner("k2");
-
- if (response1 instanceof Exception) {
- assert PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK == t2.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
- assert t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX) instanceof RollbackException;
- } else {
- assert PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK == t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
- assert t2.execute(PerCacheExecutorThread.Operations.COMMIT_TX) instanceof RollbackException;
- }
- assert lockManager.getNumberOfLocksHeld() == 0;
- assertEquals(lockManager.getDetectedLocalDeadlocks(), 1);
- }
-
-}
Deleted: branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,319 +0,0 @@
-package org.infinispan.tx;
-
-import org.infinispan.api.mvcc.LockAssert;
-import org.infinispan.commands.ReplicableCommand;
-import org.infinispan.config.Configuration;
-import org.infinispan.context.impl.NonTxInvocationContext;
-import org.infinispan.interceptors.DeadlockDetectingInterceptor;
-import org.infinispan.interceptors.InterceptorChain;
-import org.infinispan.remoting.ReplicationException;
-import org.infinispan.remoting.responses.Response;
-import org.infinispan.remoting.rpc.ResponseFilter;
-import org.infinispan.remoting.rpc.ResponseMode;
-import org.infinispan.remoting.rpc.RpcManager;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.remoting.transport.Transport;
-import org.infinispan.statetransfer.StateTransferException;
-import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.test.PerCacheExecutorThread;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.util.concurrent.NotifyingNotifiableFuture;
-import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
-import org.infinispan.util.concurrent.locks.LockManager;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * Functional test for deadlock detection.
- *
- * @author Mircea.Markus at jboss.com
- */
- at Test(testName = "tx.ReplDeadlockDetectionTest", groups = "functional")
-public class ReplDeadlockDetectionTest extends MultipleCacheManagersTest {
-
- protected ControlledRpcManager controlledRpcManager1;
- protected ControlledRpcManager controlledRpcManager2;
- protected CountDownLatch replicationLatch;
- protected PerCacheExecutorThread t1;
- protected PerCacheExecutorThread t2;
- protected DeadlockDetectingLockManager ddLm1;
- protected DeadlockDetectingLockManager ddLm2;
-
- protected Configuration.CacheMode cacheMode = Configuration.CacheMode.REPL_SYNC;
-
- protected void createCacheManagers() throws Throwable {
- Configuration config = getDefaultClusteredConfig(cacheMode, true);
- config.setEnableDeadlockDetection(true);
- config.setSyncCommitPhase(true);
- config.setSyncRollbackPhase(true);
- config.setUseLockStriping(false);
- assert config.isEnableDeadlockDetection();
- createClusteredCaches(2, "test", config);
- assert config.isEnableDeadlockDetection();
-
- assert cache(0, "test").getConfiguration().isEnableDeadlockDetection();
- assert cache(1, "test").getConfiguration().isEnableDeadlockDetection();
- assert !cache(0, "test").getConfiguration().isExposeJmxStatistics();
- assert !cache(1, "test").getConfiguration().isExposeJmxStatistics();
-
- ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0, "test"))).setExposeJmxStats(true);
- ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1, "test"))).setExposeJmxStats(true);
-
- RpcManager rpcManager1 = TestingUtil.extractComponent(cache(0, "test"), RpcManager.class);
- RpcManager rpcManager2 = TestingUtil.extractComponent(cache(1, "test"), RpcManager.class);
-
- controlledRpcManager1 = new ControlledRpcManager(rpcManager1);
- controlledRpcManager2 = new ControlledRpcManager(rpcManager2);
- TestingUtil.replaceComponent(cache(0, "test"), RpcManager.class, controlledRpcManager1, true);
- TestingUtil.replaceComponent(cache(1, "test"), RpcManager.class, controlledRpcManager2, true);
-
- assert TestingUtil.extractComponent(cache(0, "test"), RpcManager.class) instanceof ControlledRpcManager;
- assert TestingUtil.extractComponent(cache(1, "test"), RpcManager.class) instanceof ControlledRpcManager;
-
- ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0, "test"));
- ddLm2 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1, "test"));
- }
-
-
- @BeforeMethod
- public void beforeMethod() {
- t1 = new PerCacheExecutorThread(cache(0, "test"), 1);
- t2 = new PerCacheExecutorThread(cache(1, "test"), 2);
- replicationLatch = new CountDownLatch(1);
- controlledRpcManager1.setReplicationLatch(replicationLatch);
- controlledRpcManager2.setReplicationLatch(replicationLatch);
- log.trace("_________________________ Here it begins");
- }
-
- @AfterMethod
- public void afterMethod() {
- t1.stopThread();
- t2.stopThread();
- ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0, "test"))).resetStatistics();
- ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1, "test"))).resetStatistics();
- }
-
- public void testExpectedInnerStructure() {
- LockManager lockManager = TestingUtil.extractComponent(cache(0, "test"), LockManager.class);
- assert lockManager instanceof DeadlockDetectingLockManager;
-
- InterceptorChain ic = TestingUtil.extractComponent(cache(0, "test"), InterceptorChain.class);
- assert ic.containsInterceptorType(DeadlockDetectingInterceptor.class);
- }
-
- public void testDeadlockDetectedTwoTransactions() throws Exception {
- t1.setKeyValue("key", "value1");
- t2.setKeyValue("key", "value2");
- assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
- assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
- System.out.println("After begin");
-
- t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- t2.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
- System.out.println("After put key value");
-
- t1.clearResponse();
- t2.clearResponse();
-
- t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
- t2.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
-
- System.out.println("Now replication is triggered");
- replicationLatch.countDown();
-
-
- Object t1Commit = t1.waitForResponse();
- Object t2Commit = t2.waitForResponse();
- System.out.println("After commit: " + t1Commit + ", " + t2Commit);
-
- assert xor(t1Commit instanceof Exception, t2Commit instanceof Exception) : "only one thread must be failing " + t1Commit + "," + t2Commit;
- System.out.println("t2Commit = " + t2Commit);
- System.out.println("t1Commit = " + t1Commit);
-
- if (t1Commit instanceof Exception) {
- System.out.println("t1 rolled back");
- Object o = cache(0, "test").get("key");
- assert o != null;
- assert o.equals("value2");
- } else {
- System.out.println("t2 rolled back");
- Object o = cache(0, "test").get("key");
- assert o != null;
- assert o.equals("value1");
- o = cache(1, "test").get("key");
- assert o != null;
- assert o.equals("value1");
- }
-
- assert ddLm1.getDetectedRemoteDeadlocks() + ddLm2.getDetectedRemoteDeadlocks() >= 1;
-
- LockManager lm1 = TestingUtil.extractComponent(cache(0, "test"), LockManager.class);
- assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
- LockManager lm2 = TestingUtil.extractComponent(cache(1, "test"), LockManager.class);
- assert !lm2.isLocked("key") : "It is locked by " + lm2.getOwner("key");
- LockAssert.assertNoLocks(cache(0, "test"));
- }
-
- public void testDeadlockDetectedOneTx() throws Exception {
- t1.setKeyValue("key", "value1");
-
- LockManager lm2 = TestingUtil.extractComponent(cache(1, "test"), LockManager.class);
- NonTxInvocationContext ctx = cache(1, "test").getAdvancedCache().getInvocationContextContainer().createNonTxInvocationContext();
- lm2.lockAndRecord("key", ctx);
- assert lm2.isLocked("key");
-
-
- assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX) : "but received " + t1.lastResponse();
- t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-
- t1.clearResponse();
- t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
-
- replicationLatch.countDown();
- System.out.println("Now replication is triggered");
-
- t1.waitForResponse();
-
-
- Object t1CommitRsp = t1.lastResponse();
-
- assert t1CommitRsp instanceof Exception : "expected exception, received " + t1.lastResponse();
-
- LockManager lm1 = TestingUtil.extractComponent(cache(0, "test"), LockManager.class);
- assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
-
- lm2.unlock("key");
- assert !lm2.isLocked("key");
- assert !lm1.isLocked("key");
- }
-
- public void testLockReleasedWhileTryingToAcquire() throws Exception {
- t1.setKeyValue("key", "value1");
-
- LockManager lm2 = TestingUtil.extractComponent(cache(1, "test"), LockManager.class);
- NonTxInvocationContext ctx = cache(1, "test").getAdvancedCache().getInvocationContextContainer().createNonTxInvocationContext();
- lm2.lockAndRecord("key", ctx);
- assert lm2.isLocked("key");
-
-
- assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX) : "but received " + t1.lastResponse();
- t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-
- t1.clearResponse();
- t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
-
- replicationLatch.countDown();
-
- Thread.sleep(3000); //just to make sure the remote tx thread managed to spin around for some times.
- lm2.unlock("key");
-
- t1.waitForResponse();
-
-
- Object t1CommitRsp = t1.lastResponse();
-
- assert t1CommitRsp == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK : "expected true, received " + t1.lastResponse();
-
- LockManager lm1 = TestingUtil.extractComponent(cache(0, "test"), LockManager.class);
- assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
-
- assert !lm2.isLocked("key");
- assert !lm1.isLocked("key");
- }
-
- public static final class ControlledRpcManager implements RpcManager {
-
- private volatile CountDownLatch replicationLatch;
-
- public ControlledRpcManager(RpcManager realOne) {
- this.realOne = realOne;
- }
-
- private RpcManager realOne;
-
- public void setReplicationLatch(CountDownLatch replicationLatch) {
- this.replicationLatch = replicationLatch;
- }
-
- public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, ResponseFilter responseFilter) {
- return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue, responseFilter);
- }
-
- public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue) {
- return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue);
- }
-
- public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout) throws Exception {
- return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout);
- }
-
- public void retrieveState(String cacheName, long timeout) throws StateTransferException {
- realOne.retrieveState(cacheName, timeout);
- }
-
- public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync) throws ReplicationException {
- waitFirst();
- realOne.broadcastRpcCommand(rpc, sync);
- }
-
- public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
- waitFirst();
- realOne.broadcastRpcCommand(rpc, sync, usePriorityQueue);
- }
-
- private void waitFirst() {
- System.out.println(Thread.currentThread().getName() + " -- replication trigger called!");
- try {
- replicationLatch.await();
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception!", e);
- }
- }
-
- public void broadcastRpcCommandInFuture(ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
- realOne.broadcastRpcCommandInFuture(rpc, future);
- }
-
- public void broadcastRpcCommandInFuture(ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
- realOne.broadcastRpcCommandInFuture(rpc, usePriorityQueue, future);
- }
-
- public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync) throws ReplicationException {
- realOne.invokeRemotely(recipients, rpc, sync);
- }
-
- public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
- realOne.invokeRemotely(recipients, rpc, sync, usePriorityQueue);
- }
-
- public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
- realOne.invokeRemotelyInFuture(recipients, rpc, future);
- }
-
- public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
- realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future);
- }
-
- public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future, long timeout) {
- realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future, timeout);
- }
-
- public Transport getTransport() {
- return realOne.getTransport();
- }
-
- public Address getCurrentStateTransferSource() {
- return realOne.getCurrentStateTransferSource();
- }
-
- @Override
- public Address getAddress() {
- return null;
- }
- }
-}
Copied: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java (from rev 2340, branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java)
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,186 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.Cache;
+import org.infinispan.commands.VisitableCommand;
+import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.interceptors.base.CommandInterceptor;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.transaction.xa.TransactionTable;
+import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import org.infinispan.util.concurrent.locks.LockManager;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Tests deadlock detection for async caches.
+ *
+ * @author Mircea.Markus at jboss.com
+ */
+ at Test(groups = "functional", testName = "tx.AsyncDeadlockDetectionTest")
+public class AsyncDeadlockDetectionTest extends MultipleCacheManagersTest {
+ private PerCacheExecutorThread t0;
+ private PerCacheExecutorThread t1;
+ private RemoteReplicationInterceptor remoteReplicationInterceptor;
+
+
+ protected void createCacheManagers() throws Throwable {
+ Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC, true);
+ config.setEnableDeadlockDetection(true);
+ config.setSyncCommitPhase(true);
+ config.setSyncRollbackPhase(true);
+ config.setUseLockStriping(false);
+ assert config.isEnableDeadlockDetection();
+ createClusteredCaches(2, "test", config);
+ assert config.isEnableDeadlockDetection();
+
+
+ remoteReplicationInterceptor = new RemoteReplicationInterceptor();
+ Cache cache0 = cache(0, "test");
+ Cache cache1 = cache(1, "test");
+ cache1.getAdvancedCache().addInterceptor(remoteReplicationInterceptor, 0);
+ assert cache0.getConfiguration().isEnableDeadlockDetection();
+ assert cache1.getConfiguration().isEnableDeadlockDetection();
+ assert !cache0.getConfiguration().isExposeJmxStatistics();
+ assert !cache1.getConfiguration().isExposeJmxStatistics();
+
+ ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0)).setExposeJmxStats(true);
+ ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1)).setExposeJmxStats(true);
+ }
+
+ @BeforeMethod
+ public void beforeMethod() {
+ Cache cache0 = cache(0, "test");
+ Cache cache1 = cache(1, "test");
+ t0 = new PerCacheExecutorThread(cache0, 0);
+ t1 = new PerCacheExecutorThread(cache1, 1);
+ }
+
+ @AfterMethod
+ public void afterMethod() {
+ Cache cache0 = cache(0, "test");
+ Cache cache1 = cache(1, "test");
+ t0.stopThread();
+ t1.stopThread();
+ ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0)).resetStatistics();
+ ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1)).resetStatistics();
+ remoteReplicationInterceptor.executionResponse = null;
+ remoteReplicationInterceptor = null;
+ t0 = null;
+ t1 = null;
+ }
+
+ public void testRemoteTxVsLocal() throws Exception {
+ Cache cache0 = cache(0, "test");
+ Cache cache1 = cache(1, "test");
+ assertEquals(PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK, t0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX));
+ t0.setKeyValue("k1", "v1_t0");
+ assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
+ t0.setKeyValue("k2", "v2_t0");
+ assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
+
+ assertEquals(PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK, t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX));
+ t1.setKeyValue("k2", "v2_t1");
+ assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
+
+ t0.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+ final LockManager lm1 = TestingUtil.extractLockManager(cache1);
+
+ eventually(new Condition() {
+ public boolean isSatisfied() throws Exception {
+ return lm1.isLocked("k1");
+ }
+ }); //now t0 replicated, acquired lock on k1 and it tries to acquire lock on k2
+
+
+ t1.setKeyValue("k1", "v1_t1");
+ t1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+
+ Object t1Response = t1.waitForResponse();
+ Object t0Response = remoteReplicationInterceptor.getResponse();
+
+ log.trace("t0Response = " + t0Response);
+ log.trace("t1Response = " + t1Response);
+
+ assert xor(t1Response instanceof DeadlockDetectedException, t0Response instanceof DeadlockDetectedException);
+ TransactionTable transactionTable1 = TestingUtil.extractComponent(cache1, TransactionTable.class);
+
+
+ if (t0Response instanceof DeadlockDetectedException) {
+ replListener(cache0).expectWithTx(PutKeyValueCommand.class, PutKeyValueCommand.class);
+ assertEquals(t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX), PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK);
+ replListener(cache0).waitForRpc();
+ assertEquals(transactionTable1.getLocalTxCount(), 0);
+ }
+
+ DeadlockDetectingLockManager ddLm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0);
+ DeadlockDetectingLockManager ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1);
+
+ assertFalse(ddLm0.isLocked("k1"));
+ assertFalse(ddLm1.isLocked("k1"));
+ assertFalse(ddLm0.isLocked("k2"));
+ assertFalse(ddLm1.isLocked("k2"));
+ TransactionTable transactionTable0 = TestingUtil.extractComponent(cache0, TransactionTable.class);
+ assertEquals(transactionTable0.getLocalTxCount(), 0);
+ for (int i = 0; i < 20; i++) {
+ if (!(transactionTable0.getRemoteTxCount() == 0)) Thread.sleep(50);
+ }
+
+ assertEquals(transactionTable0.getRemoteTxCount(), 0);
+
+ for (int i = 0; i < 20; i++) {
+ if (!(transactionTable1.getRemoteTxCount() == 0)) Thread.sleep(50);
+ }
+ assertEquals(transactionTable1.getRemoteTxCount(), 0);
+
+ if (t1Response instanceof DeadlockDetectedException) {
+ assertEquals(cache0.get("k1"), "v1_t0");
+ assertEquals(cache0.get("k2"), "v2_t0");
+ assertEquals(cache1.get("k1"), "v1_t0");
+ assertEquals(cache1.get("k2"), "v2_t0");
+ } else {
+ assertEquals(cache0.get("k1"), "v1_t1");
+ assertEquals(cache0.get("k2"), "v2_t1");
+ assertEquals(cache1.get("k1"), "v1_t1");
+ assertEquals(cache1.get("k2"), "v2_t1");
+ }
+ }
+
+
+ public static class RemoteReplicationInterceptor extends CommandInterceptor {
+
+ public volatile Object executionResponse;
+
+ @Override
+ protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
+ try {
+ return invokeNextInterceptor(ctx, command);
+ } catch (Throwable throwable) {
+ if (!ctx.isOriginLocal()) {
+ log.trace("Setting executionResponse to " + throwable);
+ executionResponse = throwable;
+ } else {
+ log.trace("Ignoring throwable " + throwable);
+ executionResponse = "NONE";
+ }
+ throw throwable;
+ }
+ }
+
+ public Object getResponse() throws Exception {
+ while (executionResponse == null) {
+ Thread.sleep(50);
+ }
+ return executionResponse;
+ }
+ }
+}
Property changes on: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,104 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+public abstract class BaseDldEagerLockingTest extends BaseDldTest {
+ protected PerCacheExecutorThread ex0;
+ protected PerCacheExecutorThread ex1;
+ protected DeadlockDetectingLockManager lm0;
+ protected DeadlockDetectingLockManager lm1;
+
+ @BeforeMethod
+ public void beforeMethod() {
+ ex0 = new PerCacheExecutorThread(cache(0), 0);
+ ex1 = new PerCacheExecutorThread(cache(1), 1);
+
+ lm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0));
+ lm0.setExposeJmxStats(true);
+ lm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1));
+ lm1.setExposeJmxStats(true);
+ }
+
+ @AfterMethod
+ public void afterMethod() {
+ ex0.stopThread();
+ ex1.stopThread();
+ }
+
+ protected void testSymmetricDld(Object k0, Object k1) throws SystemException {
+
+ long start = System.currentTimeMillis();
+
+ log.trace("Here is where the test starts");
+
+ ex0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+ ex1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+
+
+ ex0.setKeyValue(k0, "v0_0");
+ assertEquals(ex0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+ ex1.setKeyValue(k1, "v1_1");
+ assertEquals(ex1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+
+ assert lm0.isLocked(k0);
+// assert lm0.isLocked(k1);
+// assert lm1.isLocked(k0);
+ assert lm1.isLocked(k1);
+
+ log.trace("After first set of puts");
+
+ ex0.clearResponse();
+ ex1.clearResponse();
+
+ log.info("Here is where DLD happens");
+
+ ex1.setKeyValue(k0, "v0_1");
+ ex1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+ ex0.setKeyValue(k1, "v1_0");
+ ex0.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+ ex0.waitForResponse();
+ ex1.waitForResponse();
+
+ boolean b1 = ex0.lastResponse() instanceof Exception;
+ boolean b2 = ex1.lastResponse() instanceof Exception;
+ log.info("b1:", b1);
+ log.info("b2:", b2);
+ assert xor(b1, b2) : "Both are " + (b1 || b2);
+
+ assert xor(ex0.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK,
+ ex1.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK);
+
+ Object txOutcome1 = ex0.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+ Object txOutcome2 = ex1.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+ assert xor(txOutcome1 == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK, txOutcome2 == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK);
+ assert xor(txOutcome1 instanceof RollbackException, txOutcome2 instanceof RollbackException);
+
+ assert cache(0).get(k0) != null;
+ assert cache(0).get(k1) != null;
+ assert cache(1).get(k0) != null;
+ assert cache(1).get(k1) != null;
+
+ long totalDeadlocks = lm0.getTotalNumberOfDetectedDeadlocks() + lm1.getTotalNumberOfDetectedDeadlocks();
+ assert totalDeadlocks == 1 : "Expected 1 but received " + totalDeadlocks;
+
+ System.out.println("Test took " + (System.currentTimeMillis() - start) + " millis.");
+ }
+
+
+}
Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,82 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.Cache;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import org.infinispan.util.concurrent.locks.LockManager;
+
+import java.util.concurrent.CountDownLatch;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+public abstract class BaseDldLazyLockingTest extends BaseDldTest {
+
+ protected void testSymmetricDeadlock(Object k0, Object k1) {
+
+ CountDownLatch replLatch = new CountDownLatch(1);
+ rpcManager0.setReplicationLatch(replLatch);
+ rpcManager1.setReplicationLatch(replLatch);
+
+ DeadlockDetectingLockManager ddLm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0));
+ ddLm0.setExposeJmxStats(true);
+ DeadlockDetectingLockManager ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1));
+ ddLm1.setExposeJmxStats(true);
+
+
+ PerCacheExecutorThread t0 = new PerCacheExecutorThread(cache(0), 0);
+ PerCacheExecutorThread t1 = new PerCacheExecutorThread(cache(1), 1);
+
+ assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+ assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+
+ t0.setKeyValue(k0, "k0_0");
+ t1.setKeyValue(k1, "k1_0");
+
+ t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+ t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+ t0.setKeyValue(k1, "k1_0");
+ t1.setKeyValue(k0, "k0_1");
+
+ assertEquals(t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+ assertEquals(t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+
+ log.info("---Before commit");
+ t0.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+ t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+ replLatch.countDown();
+
+
+ Object t0Response = t0.waitForResponse();
+ Object t1Response = t1.waitForResponse();
+
+ assert xor(t0Response instanceof Exception, t1Response instanceof Exception);
+
+ if (t0Response instanceof Exception) {
+ Object o = cache(0).get(k0);
+ assert o != null;
+ assert o.equals("k0_1");
+ } else {
+ Object o = cache(1).get(k0);
+ assert o != null;
+ assert o.equals("k0_0");
+ }
+
+ assert ddLm0.getDetectedRemoteDeadlocks() + ddLm1.getDetectedRemoteDeadlocks() >= 1;
+
+ LockManager lm0 = TestingUtil.extractComponent(cache(0), LockManager.class);
+ assert !lm0.isLocked("key") : "It is locked by " + lm0.getOwner("key");
+ LockManager lm1 = TestingUtil.extractComponent(cache(1), LockManager.class);
+ assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
+ }
+}
Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,26 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.Cache;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+public abstract class BaseDldTest extends MultipleCacheManagersTest {
+
+ protected ControlledRpcManager rpcManager0;
+ protected ControlledRpcManager rpcManager1;
+
+ public static ControlledRpcManager replaceRpcManager(Cache cache) {
+ RpcManager rpcManager1 = TestingUtil.extractComponent(cache, RpcManager.class);
+ ControlledRpcManager controlledRpcManager1 = new ControlledRpcManager(rpcManager1);
+ TestingUtil.replaceComponent(cache, RpcManager.class, controlledRpcManager1, true);
+ return controlledRpcManager1;
+ }
+
+}
Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,118 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.commands.ReplicableCommand;
+import org.infinispan.commands.control.LockControlCommand;
+import org.infinispan.commands.remote.ClusteredGetCommand;
+import org.infinispan.remoting.ReplicationException;
+import org.infinispan.remoting.responses.Response;
+import org.infinispan.remoting.rpc.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseMode;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.remoting.transport.Transport;
+import org.infinispan.statetransfer.StateTransferException;
+import org.infinispan.util.concurrent.NotifyingNotifiableFuture;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+* @author Mircea.Markus at jboss.com
+* @since 4.2
+*/
+public final class ControlledRpcManager implements RpcManager {
+
+ private volatile CountDownLatch replicationLatch;
+
+ public ControlledRpcManager(RpcManager realOne) {
+ this.realOne = realOne;
+ }
+
+ private RpcManager realOne;
+
+ public void setReplicationLatch(CountDownLatch replicationLatch) {
+ this.replicationLatch = replicationLatch;
+ }
+
+ public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, ResponseFilter responseFilter) {
+ waitFirst(rpcCommand);
+ return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue, responseFilter);
+ }
+
+ public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue) {
+ waitFirst(rpcCommand);
+ return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue);
+ }
+
+ public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout) throws Exception {
+ waitFirst(rpcCommand);
+ return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout);
+ }
+
+ public void retrieveState(String cacheName, long timeout) throws StateTransferException {
+ realOne.retrieveState(cacheName, timeout);
+ }
+
+ public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync) throws ReplicationException {
+ waitFirst(rpc);
+ realOne.broadcastRpcCommand(rpc, sync);
+ }
+
+ public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
+ waitFirst(rpc);
+ realOne.broadcastRpcCommand(rpc, sync, usePriorityQueue);
+ }
+
+ private void waitFirst(ReplicableCommand rpcCommand) {
+ if (!(rpcCommand instanceof ClusteredGetCommand) && !(rpcCommand instanceof LockControlCommand)) {
+ System.out.println(Thread.currentThread().getName() + " -- replication trigger called!");
+ try {
+ replicationLatch.await();
+ } catch (Exception e) {
+ throw new RuntimeException("Unexpected exception!", e);
+ }
+ }
+
+ }
+
+ public void broadcastRpcCommandInFuture(ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
+ realOne.broadcastRpcCommandInFuture(rpc, future);
+ }
+
+ public void broadcastRpcCommandInFuture(ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
+ realOne.broadcastRpcCommandInFuture(rpc, usePriorityQueue, future);
+ }
+
+ public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync) throws ReplicationException {
+ realOne.invokeRemotely(recipients, rpc, sync);
+ }
+
+ public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
+ realOne.invokeRemotely(recipients, rpc, sync, usePriorityQueue);
+ }
+
+ public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
+ realOne.invokeRemotelyInFuture(recipients, rpc, future);
+ }
+
+ public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
+ realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future);
+ }
+
+ public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future, long timeout) {
+ realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future, timeout);
+ }
+
+ public Transport getTransport() {
+ return realOne.getTransport();
+ }
+
+ public Address getCurrentStateTransferSource() {
+ return realOne.getCurrentStateTransferSource();
+ }
+
+ public Address getAddress() {
+ return realOne.getAddress();
+ }
+}
Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,57 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.affinity.KeyAffinityService;
+import org.infinispan.affinity.KeyAffinityServiceFactory;
+import org.infinispan.affinity.RndKeyGenerator;
+import org.infinispan.config.Configuration;
+import org.infinispan.distribution.BaseDistFunctionalTest;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import javax.transaction.SystemException;
+import java.util.concurrent.Executor;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test (groups = "functional", testName = "tx.dld.DldEagerLockingDistributedTest")
+public class DldEagerLockingDistributedTest extends BaseDldEagerLockingTest {
+
+ private KeyAffinityService cas;
+ private Object k0;
+ private Object k1;
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.DIST_SYNC);
+ config.setUnsafeUnreliableReturnValues(true);
+ config.setNumOwners(1);
+ config.setEnableDeadlockDetection(true);
+ config.setUseEagerLocking(true);
+ EmbeddedCacheManager cm1 = TestCacheManagerFactory.createCacheManager(config, true);
+ EmbeddedCacheManager cm2 = TestCacheManagerFactory.createCacheManager(config, true);
+ registerCacheManager(cm1);
+ registerCacheManager(cm2);
+ TestingUtil.blockUntilViewsReceived(10000, cache(0), cache(1));
+ BaseDistFunctionalTest.RehashWaiter.waitForInitRehashToComplete(cache(0), cache(1));
+
+ cas = KeyAffinityServiceFactory.newKeyAffinityService(cache(0), new Executor() {
+ public void execute(Runnable command) {
+ new Thread(command).start();
+ }
+ }, new RndKeyGenerator(), 2, true);
+ k0 = cas.getKeyForAddress(address(0));
+ k1 = cas.getKeyForAddress(address(1));
+ cas.stop();
+ }
+
+ public void testSymmetricDeadlock() throws SystemException {
+ testSymmetricDld(k0, k1);
+ }
+}
Copied: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java (from rev 2340, branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java)
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,63 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.config.Configuration;
+import org.infinispan.context.Flag;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.TimeoutException;
+import org.testng.annotations.Test;
+
+import javax.transaction.TransactionManager;
+
+/**
+ * @author Mircea.Markus at jboss.com
+ * @since 4.1
+ */
+ at Test(groups = "functional", testName = "tx.EagerTxDeadlockDetectionTest")
+public class DldEagerLockingReplicationTest extends BaseDldEagerLockingTest {
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ Configuration configuration = getConfiguration();
+ createClusteredCaches(2, configuration);
+ TestingUtil.blockUntilViewsReceived(1000, cache(0), cache(1));
+ }
+
+ protected Configuration getConfiguration() throws Exception {
+ Configuration configuration = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
+ configuration.setUseEagerLocking(true);
+ configuration.setEnableDeadlockDetection(true);
+ configuration.setUseLockStriping(false);
+ return configuration;
+ }
+
+ public void testDeadlock() throws Exception {
+ testSymmetricDld("k1", "k2");
+ }
+
+ /**
+ * On eager locking, remote locks are being acquired at first, and then local locks. This is for specifying the
+ * behavior whe remote acquisition succeeds and local fails.
+ */
+ public void testDeadlockFailedToAcquireLocalLocks() throws Exception {
+ //first acquire a local lock on k1
+ TransactionManager tm = TestingUtil.getTransactionManager(cache(0));
+ tm.begin();
+ cache(0).getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL).put("k1","v1");
+ assert lm0.isLocked("k1");
+ assert !lm1.isLocked("k1");
+ try {
+ ex0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+ ex0.setKeyValue("k1", "v1_1");
+ ex0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+ assert ex0.lastResponse() instanceof TimeoutException;
+ eventually(new Condition() {
+ public boolean isSatisfied() throws Exception {
+ return !lm1.isLocked("k1");
+ }
+ });
+ } finally {
+ tm.rollback();
+ }
+ }
+}
Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,61 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.affinity.KeyAffinityService;
+import org.infinispan.affinity.KeyAffinityServiceFactory;
+import org.infinispan.affinity.RndKeyGenerator;
+import org.infinispan.config.Configuration;
+import org.infinispan.distribution.BaseDistFunctionalTest;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Tests deadlock detection when t1 acquire (k1, k2) and te acquires (k2, k1).
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test(groups = "functional", testName = "tx.DistSymmetricDldTest")
+public class DldLazyLockingDistributionTest extends BaseDldLazyLockingTest {
+
+ private KeyAffinityService cas;
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.DIST_SYNC);
+ config.setUnsafeUnreliableReturnValues(true);
+ config.setNumOwners(1);
+ config.setEnableDeadlockDetection(true);
+ EmbeddedCacheManager cm1 = TestCacheManagerFactory.createCacheManager(config, true);
+ EmbeddedCacheManager cm2 = TestCacheManagerFactory.createCacheManager(config, true);
+ registerCacheManager(cm1);
+ registerCacheManager(cm2);
+ TestingUtil.blockUntilViewsReceived(10000, cache(0), cache(1));
+ BaseDistFunctionalTest.RehashWaiter.waitForInitRehashToComplete(cache(0), cache(1));
+
+ cas = KeyAffinityServiceFactory.newKeyAffinityService(cache(0), new Executor() {
+ public void execute(Runnable command) {
+ new Thread(command).start();
+ }
+ }, new RndKeyGenerator(), 2, true);
+
+ rpcManager0 = DldLazyLockingReplicationTest.replaceRpcManager(cache(0));
+ rpcManager1 = DldLazyLockingReplicationTest.replaceRpcManager(cache(1));
+ }
+
+ public void testSymmetricDeadlock() {
+ Object k0 = cas.getKeyForAddress(address(0));
+ Object k1 = cas.getKeyForAddress(address(1));
+ testSymmetricDeadlock(k0, k1);
+ }
+
+ @AfterClass
+ public void destroyKeyService() {
+ cas.stop();
+ }
+
+}
Copied: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java (from rev 2340, branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java)
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,212 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.api.mvcc.LockAssert;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.impl.NonTxInvocationContext;
+import org.infinispan.interceptors.DeadlockDetectingInterceptor;
+import org.infinispan.interceptors.InterceptorChain;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import org.infinispan.util.concurrent.locks.LockManager;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Functional test for deadlock detection.
+ *
+ * @author Mircea.Markus at jboss.com
+ */
+ at Test(testName = "tx.ReplDeadlockDetectionTest", groups = "functional")
+public class DldLazyLockingReplicationTest extends BaseDldLazyLockingTest {
+
+ protected CountDownLatch replicationLatch;
+ protected PerCacheExecutorThread t1;
+ protected PerCacheExecutorThread t2;
+ protected DeadlockDetectingLockManager ddLm1;
+ protected DeadlockDetectingLockManager ddLm2;
+
+ protected void createCacheManagers() throws Throwable {
+ Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
+ config.setEnableDeadlockDetection(true);
+ config.setSyncCommitPhase(true);
+ config.setSyncRollbackPhase(true);
+ config.setUseLockStriping(false);
+ assert config.isEnableDeadlockDetection();
+ createClusteredCaches(2, config);
+ assert config.isEnableDeadlockDetection();
+
+ assert cache(0).getConfiguration().isEnableDeadlockDetection();
+ assert cache(1).getConfiguration().isEnableDeadlockDetection();
+ assert !cache(0).getConfiguration().isExposeJmxStatistics();
+ assert !cache(1).getConfiguration().isExposeJmxStatistics();
+
+ ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0))).setExposeJmxStats(true);
+ ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1))).setExposeJmxStats(true);
+
+ rpcManager0 = replaceRpcManager(cache(0));
+ rpcManager1 = replaceRpcManager(cache(1));
+
+ assert TestingUtil.extractComponent(cache(0), RpcManager.class) instanceof ControlledRpcManager;
+ assert TestingUtil.extractComponent(cache(1), RpcManager.class) instanceof ControlledRpcManager;
+
+ ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0));
+ ddLm2 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1));
+ }
+
+
+ @BeforeMethod
+ public void beforeMethod() {
+ t1 = new PerCacheExecutorThread(cache(0), 1);
+ t2 = new PerCacheExecutorThread(cache(1), 2);
+ replicationLatch = new CountDownLatch(1);
+ rpcManager0.setReplicationLatch(replicationLatch);
+ rpcManager1.setReplicationLatch(replicationLatch);
+ log.trace("_________________________ Here it begins");
+ }
+
+ @AfterMethod
+ public void afterMethod() {
+ t1.stopThread();
+ t2.stopThread();
+ ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0))).resetStatistics();
+ ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1))).resetStatistics();
+ }
+
+ public void testSymmetricDeadlock() {
+ super.testSymmetricDeadlock("k0", "k1");
+ }
+
+ public void testExpectedInnerStructure() {
+ LockManager lockManager = TestingUtil.extractComponent(cache(0), LockManager.class);
+ assert lockManager instanceof DeadlockDetectingLockManager;
+
+ InterceptorChain ic = TestingUtil.extractComponent(cache(0), InterceptorChain.class);
+ assert ic.containsInterceptorType(DeadlockDetectingInterceptor.class);
+ }
+
+ public void testSameKeyDeadlock() throws Exception {
+ t1.setKeyValue("key", "value1");
+ t2.setKeyValue("key", "value2");
+ assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+ assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+ System.out.println("After begin");
+
+ t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+ t2.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+ System.out.println("After put key value");
+
+ t1.clearResponse();
+ t2.clearResponse();
+
+ t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+ t2.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+ System.out.println("Now replication is triggered");
+ replicationLatch.countDown();
+
+
+ Object t1Commit = t1.waitForResponse();
+ Object t2Commit = t2.waitForResponse();
+ System.out.println("After commit: " + t1Commit + ", " + t2Commit);
+
+ assert xor(t1Commit instanceof Exception, t2Commit instanceof Exception) : "only one thread must be failing " + t1Commit + "," + t2Commit;
+ System.out.println("t2Commit = " + t2Commit);
+ System.out.println("t1Commit = " + t1Commit);
+
+ if (t1Commit instanceof Exception) {
+ System.out.println("t1 rolled back");
+ Object o = cache(0).get("key");
+ assert o != null;
+ assert o.equals("value2");
+ } else {
+ System.out.println("t2 rolled back");
+ Object o = cache(0).get("key");
+ assert o != null;
+ assert o.equals("value1");
+ o = cache(1).get("key");
+ assert o != null;
+ assert o.equals("value1");
+ }
+
+ assert ddLm1.getDetectedRemoteDeadlocks() + ddLm2.getDetectedRemoteDeadlocks() >= 1;
+
+ LockManager lm1 = TestingUtil.extractComponent(cache(0), LockManager.class);
+ assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
+ LockManager lm2 = TestingUtil.extractComponent(cache(1), LockManager.class);
+ assert !lm2.isLocked("key") : "It is locked by " + lm2.getOwner("key");
+ LockAssert.assertNoLocks(cache(0));
+ }
+
+ public void testDeadlockDetectedOneTx() throws Exception {
+ t1.setKeyValue("key", "value1");
+
+ LockManager lm2 = TestingUtil.extractComponent(cache(1), LockManager.class);
+ NonTxInvocationContext ctx = cache(1).getAdvancedCache().getInvocationContextContainer().createNonTxInvocationContext();
+ lm2.lockAndRecord("key", ctx);
+ assert lm2.isLocked("key");
+
+
+ assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX) : "but received " + t1.lastResponse();
+ t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+ t1.clearResponse();
+ t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+ replicationLatch.countDown();
+ System.out.println("Now replication is triggered");
+
+ t1.waitForResponse();
+
+
+ Object t1CommitRsp = t1.lastResponse();
+
+ assert t1CommitRsp instanceof Exception : "expected exception, received " + t1.lastResponse();
+
+ LockManager lm1 = TestingUtil.extractComponent(cache(0), LockManager.class);
+ assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
+
+ lm2.unlock("key");
+ assert !lm2.isLocked("key");
+ assert !lm1.isLocked("key");
+ }
+
+ public void testLockReleasedWhileTryingToAcquire() throws Exception {
+ t1.setKeyValue("key", "value1");
+
+ LockManager lm2 = TestingUtil.extractComponent(cache(1), LockManager.class);
+ NonTxInvocationContext ctx = cache(1).getAdvancedCache().getInvocationContextContainer().createNonTxInvocationContext();
+ lm2.lockAndRecord("key", ctx);
+ assert lm2.isLocked("key");
+
+
+ assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX) : "but received " + t1.lastResponse();
+ t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+ t1.clearResponse();
+ t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+ replicationLatch.countDown();
+
+ Thread.sleep(3000); //just to make sure the remote tx thread managed to spin around for some times.
+ lm2.unlock("key");
+
+ t1.waitForResponse();
+
+
+ Object t1CommitRsp = t1.lastResponse();
+
+ assert t1CommitRsp == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK : "expected true, received " + t1.lastResponse();
+
+ LockManager lm1 = TestingUtil.extractComponent(cache(0), LockManager.class);
+ assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
+
+ assert !lm2.isLocked("key");
+ assert !lm1.isLocked("key");
+ }
+
+}
Property changes on: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java (from rev 2340, branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java)
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,190 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.config.Configuration;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.RollbackException;
+
+/**
+ * Tests deadlock detection functionality for local caches.
+ *
+ * @author Mircea.Markus at jboss.com
+ */
+ at Test(groups = "functional", testName = "tx.LocalDeadlockDetectionTest")
+public class LocalDeadlockDetectionTest extends SingleCacheManagerTest {
+
+ private PerCacheExecutorThread t1;
+ private PerCacheExecutorThread t2;
+ private DeadlockDetectingLockManager lockManager;
+ private Object response1;
+ private Object response2;
+
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ cacheManager = TestCacheManagerFactory.createLocalCacheManager();
+ Configuration configuration = getDefaultStandaloneConfig(true);
+ configuration.setEnableDeadlockDetection(true);
+ configuration.setUseLockStriping(false);
+ configuration.setExposeJmxStatistics(true);
+ cacheManager.defineConfiguration("test", configuration);
+ cache = cacheManager.getCache("test");
+ lockManager = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache);
+ return cacheManager;
+ }
+
+ @BeforeMethod
+ public void startExecutors() {
+ t1 = new PerCacheExecutorThread(cache, 0);
+ t2 = new PerCacheExecutorThread(cache, 1);
+ lockManager.resetStatistics();
+ }
+
+
+ @AfterMethod
+ public void stopExecutors() {
+ t1.stopThread();
+ t2.stopThread();
+ }
+
+ public void testDldPutAndPut() {
+ testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
+ PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+ if (response1 instanceof Exception) {
+ assertEquals("value_1_t2", cache.get("k1"));
+ assertEquals("value_2_t2", cache.get("k2"));
+ } else {
+ assertEquals("value_1_t1", cache.get("k1"));
+ assertEquals("value_2_t1", cache.get("k2"));
+ }
+ }
+
+ public void testDldPutAndRemove() {
+ testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
+ PerCacheExecutorThread.Operations.REMOVE_KEY);
+ if (response1 instanceof Exception) {
+ assertEquals(cache.get("k1"), null);
+ assertEquals("value_2_t2", cache.get("k2"));
+ } else {
+ assertEquals("value_1_t1", cache.get("k1"));
+ assertEquals(null, cache.get("k2"));
+ }
+ }
+
+ public void testDldRemoveAndPut() {
+ testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REMOVE_KEY,
+ PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+ if (response1 instanceof Exception) {
+ System.out.println("t1 failure");
+ assertEquals(cache.get("k1"), "value_1_t2");
+ assertEquals(cache.get("k2"), null);
+ } else {
+ System.out.println("t2 failure");
+ assertEquals(cache.get("k1"), null);
+ assertEquals(cache.get("k2"), "value_2_t1");
+ }
+ }
+
+ public void testDldRemoveAndRemove() {
+ testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REMOVE_KEY,
+ PerCacheExecutorThread.Operations.REMOVE_KEY);
+ if (response1 instanceof Exception) {
+ System.out.println("t1 failure");
+ assertEquals(cache.get("k1"), null);
+ assertEquals(cache.get("k2"), null);
+ } else {
+ System.out.println("t2 failure");
+ assertEquals(cache.get("k1"), null);
+ assertEquals(cache.get("k2"), null);
+ }
+ }
+
+ public void testDldPutAndReplace() {
+
+ cache.put("k1", "initial_1");
+ cache.put("k2", "initial_2");
+
+ testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
+ PerCacheExecutorThread.Operations.REPLACE_KEY_VALUE);
+ if (response1 instanceof Exception) {
+ System.out.println("t1 failure");
+ assertEquals(cache.get("k1"), "value_1_t2");
+ assertEquals(cache.get("k2"), "value_2_t2");
+ } else {
+ System.out.println("t2 failure");
+ assertEquals(cache.get("k1"), "value_1_t1");
+ assertEquals(cache.get("k2"), "value_2_t1");
+ }
+ }
+
+ public void testDldReplaceAndPut() {
+
+ cache.put("k1", "initial_1");
+ cache.put("k2", "initial_2");
+
+ testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REPLACE_KEY_VALUE,
+ PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+ if (response1 instanceof Exception) {
+ System.out.println("t1 failure");
+ assertEquals(cache.get("k1"), "value_1_t2");
+ assertEquals(cache.get("k2"), "value_2_t2");
+ } else {
+ System.out.println("t2 failure");
+ assertEquals(cache.get("k1"), "value_1_t1");
+ assertEquals(cache.get("k2"), "value_2_t1");
+ }
+ }
+
+
+ private void testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations firstOperation, PerCacheExecutorThread.Operations secondOperation) {
+
+ assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+ assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+ System.out.println("After begin");
+
+ t1.setKeyValue("k1", "value_1_t1");
+ t2.setKeyValue("k2", "value_2_t2");
+
+ assertEquals(t1.execute(firstOperation), firstOperation.getCorrespondingOkResult());
+ assertEquals(t2.execute(firstOperation), firstOperation.getCorrespondingOkResult());
+
+ assert lockManager.isLocked("k1");
+ assert lockManager.isLocked("k2");
+
+
+ t1.setKeyValue("k2", "value_2_t1");
+ t2.setKeyValue("k1", "value_1_t2");
+ t1.executeNoResponse(secondOperation);
+ t2.executeNoResponse(secondOperation);
+
+ response1 = t1.waitForResponse();
+ response2 = t2.waitForResponse();
+
+ assert xor(response1 instanceof DeadlockDetectedException, response2 instanceof DeadlockDetectedException) : "expected one and only one exception: " + response1 + ", " + response2;
+ assert xor(response1 == secondOperation.getCorrespondingOkResult(), response2 == secondOperation.getCorrespondingOkResult()) : "expected one and only one exception: " + response1 + ", " + response2;
+
+ assert lockManager.isLocked("k1");
+ assert lockManager.isLocked("k2");
+ assert lockManager.getOwner("k1") == lockManager.getOwner("k2");
+
+ if (response1 instanceof Exception) {
+ assert PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK == t2.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+ assert t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX) instanceof RollbackException;
+ } else {
+ assert PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK == t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+ assert t2.execute(PerCacheExecutorThread.Operations.COMMIT_TX) instanceof RollbackException;
+ }
+ assert lockManager.getNumberOfLocksHeld() == 0;
+ assertEquals(lockManager.getDetectedLocalDeadlocks(), 1);
+ }
+
+}
Property changes on: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: branches/4.2.x/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java 2010-09-15 00:16:18 UTC (rev 2372)
@@ -88,7 +88,7 @@
Lock mockLock = createNiceMock(Lock.class);
expect(lc.acquireLock("k", SPIN_DURATION, TimeUnit.MILLISECONDS)).andReturn(mockLock);
lockOwner.setRemote(false);
- lockOwner.setLockLocalLockIntention("k");
+ lockOwner.setLockIntention("k");
lockManager.setOwner(lockOwner);
lockManager.setOwnsLock(true);
replay(lc);
Modified: branches/4.2.x/pom.xml
===================================================================
--- branches/4.2.x/pom.xml 2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/pom.xml 2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,7 +1,5 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@@ -45,6 +43,7 @@
<module>demos/lucene-directory-demo</module>
<module>demos/gridfs-webdav</module>
<module>tools</module>
+ <module>continuous-query</module>
</modules>
<profiles>
@@ -298,4 +297,4 @@
</profile>
</profiles>
-</project>
+</project>
\ No newline at end of file
More information about the infinispan-commits
mailing list