You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/12/02 09:25:23 UTC
[17/19] ignite git commit: ignite-4285 For serializable txs allow
multiple threads to get read lock for the same key
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
index b005b29..d77933e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
@@ -36,6 +36,7 @@ import org.apache.ignite.internal.NodeStoppingException;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
+import org.apache.ignite.internal.processors.cache.CacheLockCandidates;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
@@ -346,25 +347,6 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
}
/**
- * @param cached Entry.
- * @return {@code True} if locked.
- * @throws GridCacheEntryRemovedException If removed.
- */
- private boolean locked(GridCacheEntryEx cached) throws GridCacheEntryRemovedException {
- return (cached.lockedLocally(lockVer) && filter(cached)); // If filter failed, lock is failed.
- }
-
- /**
- * @param cached Entry.
- * @param owner Lock owner.
- * @return {@code True} if locked.
- */
- private boolean locked(GridCacheEntryEx cached, GridCacheMvccCandidate owner) {
- // Reentry-aware check (if filter failed, lock is failed).
- return owner != null && owner.matches(lockVer, cctx.nodeId(), threadId) && filter(cached);
- }
-
- /**
* Adds entry to future.
*
* @param entry Entry to add.
@@ -392,11 +374,11 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
threadId,
lockVer,
null,
- null,
timeout,
/*reenter*/false,
inTx(),
- implicitSingle()
+ implicitSingle(),
+ false
);
if (c == null && timeout < 0) {
@@ -575,10 +557,10 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
break; // While.
try {
- GridCacheMvccCandidate owner = entry.readyLock(lockVer);
+ CacheLockCandidates owners = entry.readyLock(lockVer);
if (timeout < 0) {
- if (owner == null || !owner.version().equals(lockVer)) {
+ if (owners == null || !owners.hasCandidate(lockVer)) {
// We did not send any requests yet.
onFailed(false);
@@ -587,9 +569,9 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
}
if (log.isDebugEnabled()) {
- if (!locked(entry, owner))
- log.debug("Entry is not locked (will keep waiting) [entry=" + entry +
- ", fut=" + this + ']');
+ log.debug("Current lock owners [entry=" + entry +
+ ", owners=" + owners +
+ ", fut=" + this + ']');
}
break; // Inner while loop.
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
index 6b437b1..01bc4e0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
@@ -273,7 +273,6 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
nodeId,
req.threadId(),
req.version(),
- req.timeout(),
tx != null,
tx != null && tx.implicitSingle(),
null
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index 1dbda69..a759194 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
@@ -40,6 +40,7 @@ import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheInvokeEntry;
+import org.apache.ignite.internal.processors.cache.CacheLockCandidates;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
@@ -629,10 +630,10 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
try {
assert txEntry.explicitVersion() == null || entry.lockedBy(txEntry.explicitVersion());
- GridCacheMvccCandidate c = entry.readyLock(tx.xidVersion());
+ CacheLockCandidates owners = entry.readyLock(tx.xidVersion());
if (log.isDebugEnabled())
- log.debug("Current lock owner for entry [owner=" + c + ", entry=" + entry + ']');
+ log.debug("Current lock owners for entry [owner=" + owners + ", entry=" + entry + ']');
break; // While.
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
index b0eea01..5557d34 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
@@ -312,14 +312,14 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
null,
threadId,
lockVer,
- timeout,
true,
tx.entry(txKey).locked(),
inTx(),
inTx() && tx.implicitSingle(),
false,
false,
- null);
+ null,
+ false);
cand.topologyVersion(topVer);
}
@@ -332,14 +332,14 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
null,
threadId,
lockVer,
- timeout,
true,
false,
inTx(),
inTx() && tx.implicitSingle(),
false,
false,
- null);
+ null,
+ false);
cand.topologyVersion(topVer);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java
index d495f83..30fc213 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheEntry.java
@@ -21,6 +21,7 @@ import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.CacheLockCandidates;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
@@ -444,7 +445,8 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
long timeout,
boolean reenter,
boolean tx,
- boolean implicitSingle) throws GridCacheEntryRemovedException {
+ boolean implicitSingle,
+ boolean read) throws GridCacheEntryRemovedException {
return addNearLocal(
null,
threadId,
@@ -453,7 +455,8 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
timeout,
reenter,
tx,
- implicitSingle
+ implicitSingle,
+ read
);
}
@@ -468,10 +471,11 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
* @param reenter Reentry flag.
* @param tx Transaction flag.
* @param implicitSingle Implicit flag.
+ * @param read Read lock flag.
* @return New candidate.
* @throws GridCacheEntryRemovedException If entry has been removed.
*/
- @Nullable public GridCacheMvccCandidate addNearLocal(
+ @Nullable GridCacheMvccCandidate addNearLocal(
@Nullable UUID dhtNodeId,
long threadId,
GridCacheVersion ver,
@@ -479,10 +483,11 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
long timeout,
boolean reenter,
boolean tx,
- boolean implicitSingle)
+ boolean implicitSingle,
+ boolean read)
throws GridCacheEntryRemovedException {
- GridCacheMvccCandidate prev;
- GridCacheMvccCandidate owner;
+ CacheLockCandidates prev;
+ CacheLockCandidates owner = null;
GridCacheMvccCandidate cand;
CacheObject val;
@@ -505,7 +510,7 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
if (c != null)
return reenter ? c.reenter() : null;
- prev = mvcc.anyOwner();
+ prev = mvcc.allOwners();
boolean emptyBefore = mvcc.isEmpty();
@@ -520,14 +525,12 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
dhtNodeId,
threadId,
ver,
- timeout,
tx,
- implicitSingle);
+ implicitSingle,
+ read);
cand.topologyVersion(topVer);
- owner = mvcc.anyOwner();
-
boolean emptyAfter = mvcc.isEmpty();
checkCallbacks(emptyBefore, emptyAfter);
@@ -536,6 +539,8 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
if (emptyAfter)
mvccExtras(null);
+ else
+ owner = mvcc.allOwners();
}
// This call must be outside of synchronization.
@@ -572,8 +577,8 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
* @return Removed candidate, or <tt>null</tt> if thread still holds the lock.
*/
@Nullable @Override public GridCacheMvccCandidate removeLock() {
- GridCacheMvccCandidate prev = null;
- GridCacheMvccCandidate owner = null;
+ CacheLockCandidates prev = null;
+ CacheLockCandidates owner = null;
CacheObject val;
@@ -585,7 +590,7 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
GridCacheMvcc mvcc = mvccExtras();
if (mvcc != null) {
- prev = mvcc.anyOwner();
+ prev = mvcc.allOwners();
boolean emptyBefore = mvcc.isEmpty();
@@ -605,7 +610,7 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
mvcc.remove(cand.version());
- owner = mvcc.anyOwner();
+ owner = mvcc.allOwners();
}
else
return null;
@@ -630,13 +635,12 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
cctx.mvcc().removeExplicitLock(cand);
- if (prev != null && owner != prev)
- checkThreadChain(prev);
+ checkThreadChain(cand);
// This call must be outside of synchronization.
checkOwnerChanged(prev, owner, val);
- return owner != prev ? prev : null;
+ return cand;
}
/** {@inheritDoc} */
@@ -648,7 +652,7 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
/**
* @throws GridCacheEntryRemovedException If entry was removed.
*/
- public synchronized void reserveEviction() throws GridCacheEntryRemovedException {
+ synchronized void reserveEviction() throws GridCacheEntryRemovedException {
checkObsolete();
evictReservations++;
@@ -657,7 +661,7 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
/**
*
*/
- public synchronized void releaseEviction() {
+ synchronized void releaseEviction() {
assert evictReservations > 0 : this;
assert !obsolete() : this;
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
index 3d9b6ab..2431379 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
@@ -325,7 +325,8 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture<Boolean
timeout,
!inTx(),
inTx(),
- implicitSingleTx()
+ implicitSingleTx(),
+ false
);
if (inTx()) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
index cf5d2e2..7ac3295 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
@@ -356,7 +356,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
nodeId,
req.threadId(),
req.version(),
- req.timeout(),
tx != null,
tx != null && tx.implicitSingle(),
req.owned(entry.key())
@@ -577,9 +576,7 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
if (!primary.isLocal()) {
assert req != null;
- req.addKey(
- entry.key(),
- ctx);
+ req.addKey(entry.key(), ctx);
}
else
locKeys.add(cacheKey);
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java
index 10fa116..bc61333 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalCacheEntry.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.processors.cache.local;
+import org.apache.ignite.internal.processors.cache.CacheLockCandidates;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
@@ -29,9 +30,6 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.jetbrains.annotations.Nullable;
-import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_LOCKED;
-import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_UNLOCKED;
-
/**
* Cache entry for local caches.
*/
@@ -46,7 +44,7 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
* @param hash Key hash value.
* @param val Entry value.
*/
- public GridLocalCacheEntry(
+ GridLocalCacheEntry(
GridCacheContext ctx,
KeyCacheObject key,
int hash,
@@ -71,10 +69,11 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
* @param reenter Reentry flag.
* @param tx Transaction flag.
* @param implicitSingle Implicit transaction flag.
+ * @param read Read lock flag.
* @return New candidate.
* @throws GridCacheEntryRemovedException If entry has been removed.
*/
- @Nullable public GridCacheMvccCandidate addLocal(
+ @Nullable GridCacheMvccCandidate addLocal(
long threadId,
GridCacheVersion ver,
@Nullable GridCacheVersion serOrder,
@@ -83,14 +82,14 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
boolean reenter,
boolean tx,
boolean implicitSingle,
- boolean keepBinary
+ boolean read
) throws GridCacheEntryRemovedException {
- GridCacheMvccCandidate prev;
- GridCacheMvccCandidate cand;
- GridCacheMvccCandidate owner;
+ assert serReadVer == null || serOrder != null;
CacheObject val;
- boolean hasVal;
+ GridCacheMvccCandidate cand;
+ CacheLockCandidates prev;
+ CacheLockCandidates owner = null;
synchronized (this) {
checkObsolete();
@@ -108,7 +107,7 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
mvccExtras(mvcc);
}
- prev = mvcc.localOwner();
+ prev = mvcc.localOwners();
cand = mvcc.addLocal(
this,
@@ -121,59 +120,50 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
reenter,
tx,
implicitSingle,
- /*dht-local*/false
+ /*dht-local*/false,
+ read
);
- owner = mvcc.localOwner();
-
- val = this.val;
-
- hasVal = hasValueUnlocked();
-
if (mvcc.isEmpty())
mvccExtras(null);
- }
-
- if (cand != null) {
- if (!cand.reentry())
- cctx.mvcc().addNext(cctx, cand);
+ else
+ owner = mvcc.localOwners();
- // Event notification.
- if (cctx.events().isRecordable(EVT_CACHE_OBJECT_LOCKED))
- cctx.events().addEvent(partition(), key, cand.nodeId(), cand, EVT_CACHE_OBJECT_LOCKED, val, hasVal,
- val, hasVal, null, null, null, keepBinary);
+ val = this.val;
}
- checkOwnerChanged(prev, owner);
+ if (cand != null && !cand.reentry())
+ cctx.mvcc().addNext(cctx, cand);
+
+ checkOwnerChanged(prev, owner, val);
return cand;
}
/**
- *
* @param cand Candidate.
- * @return Current owner.
*/
- @Nullable public GridCacheMvccCandidate readyLocal(GridCacheMvccCandidate cand) {
- GridCacheMvccCandidate prev = null;
- GridCacheMvccCandidate owner = null;
+ void readyLocal(GridCacheMvccCandidate cand) {
+ CacheObject val;
+ CacheLockCandidates prev = null;
+ CacheLockCandidates owner = null;
synchronized (this) {
GridCacheMvcc mvcc = mvccExtras();
if (mvcc != null) {
- prev = mvcc.localOwner();
+ prev = mvcc.localOwners();
owner = mvcc.readyLocal(cand);
if (mvcc.isEmpty())
mvccExtras(null);
}
- }
- checkOwnerChanged(prev, owner);
+ val = this.val;
+ }
- return owner;
+ checkOwnerChanged(prev, owner, val);
}
/** {@inheritDoc} */
@@ -181,7 +171,7 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
long timeout,
@Nullable GridCacheVersion serOrder,
GridCacheVersion serReadVer,
- boolean keepBinary)
+ boolean read)
throws GridCacheEntryRemovedException {
GridCacheMvccCandidate cand = addLocal(
tx.threadId(),
@@ -192,7 +182,7 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
/*reenter*/false,
/*tx*/true,
tx.implicitSingle(),
- keepBinary
+ read
);
if (cand != null) {
@@ -206,50 +196,32 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
/**
* Rechecks if lock should be reassigned.
- *
- * @return Current owner.
*/
- @Nullable public GridCacheMvccCandidate recheck() {
- GridCacheMvccCandidate prev = null;
- GridCacheMvccCandidate owner = null;
+ public void recheck() {
+ CacheObject val;
+ CacheLockCandidates prev = null;
+ CacheLockCandidates owner = null;
synchronized (this) {
GridCacheMvcc mvcc = mvccExtras();
if (mvcc != null) {
- prev = mvcc.localOwner();
+ prev = mvcc.allOwners();
owner = mvcc.recheck();
if (mvcc.isEmpty())
mvccExtras(null);
}
- }
-
- checkOwnerChanged(prev, owner);
-
- return owner;
- }
- /**
- * @param prev Previous owner.
- * @param owner Current owner.
- */
- private void checkOwnerChanged(GridCacheMvccCandidate prev, GridCacheMvccCandidate owner) {
- assert !Thread.holdsLock(this);
-
- if (owner != prev) {
- cctx.mvcc().callback().onOwnerChanged(this, prev, owner);
-
- if (owner != null)
- checkThreadChain(owner);
+ val = this.val;
}
+
+ checkOwnerChanged(prev, owner, val);
}
- /**
- * @param owner Starting candidate in the chain.
- */
- private void checkThreadChain(GridCacheMvccCandidate owner) {
+ /** {@inheritDoc} */
+ @Override protected void checkThreadChain(GridCacheMvccCandidate owner) {
assert !Thread.holdsLock(this);
assert owner != null;
@@ -298,62 +270,50 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
*
* @param threadId Thread ID.
*/
- void releaseLocal(long threadId) {
- GridCacheMvccCandidate prev = null;
- GridCacheMvccCandidate owner = null;
-
+ private void releaseLocal(long threadId) {
CacheObject val;
- boolean hasVal;
+ CacheLockCandidates prev = null;
+ CacheLockCandidates owner = null;
synchronized (this) {
GridCacheMvcc mvcc = mvccExtras();
if (mvcc != null) {
- prev = mvcc.localOwner();
+ prev = mvcc.localOwners();
- owner = mvcc.releaseLocal(threadId);
+ mvcc.releaseLocal(threadId);
if (mvcc.isEmpty())
mvccExtras(null);
+ else
+ owner = mvcc.allOwners();
}
val = this.val;
- hasVal = hasValueUnlocked();
}
- if (prev != null && owner != prev) {
- checkThreadChain(prev);
+ if (prev != null) {
+ for (int i = 0; i < prev.size(); i++) {
+ GridCacheMvccCandidate cand = prev.candidate(i);
- // Event notification.
- if (cctx.events().isRecordable(EVT_CACHE_OBJECT_UNLOCKED))
- cctx.events().addEvent(partition(), key, prev.nodeId(), prev, EVT_CACHE_OBJECT_UNLOCKED, val, hasVal,
- val, hasVal, null, null, null, true);
- }
+ boolean unlocked = owner == null || !owner.hasCandidate(cand.version());
- checkOwnerChanged(prev, owner);
- }
+ if (unlocked)
+ checkThreadChain(cand);
+ }
+ }
- /**
- * Removes candidate regardless if it is owner or not.
- *
- * @param cand Candidate to remove.
- * @throws GridCacheEntryRemovedException If the entry was removed by version other
- * than one passed in.
- */
- void removeLock(GridCacheMvccCandidate cand) throws GridCacheEntryRemovedException {
- removeLock(cand.version());
+ checkOwnerChanged(prev, owner, val);
}
/** {@inheritDoc} */
@Override public boolean removeLock(GridCacheVersion ver) throws GridCacheEntryRemovedException {
- GridCacheMvccCandidate prev = null;
- GridCacheMvccCandidate owner = null;
+ CacheObject val;
+ CacheLockCandidates prev = null;
+ CacheLockCandidates owner = null;
GridCacheMvccCandidate doomed;
- CacheObject val;
- boolean hasVal;
-
synchronized (this) {
GridCacheVersion obsoleteVer = obsoleteVersionExtras();
@@ -365,28 +325,23 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
doomed = mvcc == null ? null : mvcc.candidate(ver);
if (doomed != null) {
- prev = mvcc.localOwner();
+ prev = mvcc.allOwners();
- owner = mvcc.remove(ver);
+ mvcc.remove(ver);
if (mvcc.isEmpty())
mvccExtras(null);
+ else
+ owner = mvcc.allOwners();
}
val = this.val;
- hasVal = hasValueUnlocked();
}
- if (doomed != null) {
+ if (doomed != null)
checkThreadChain(doomed);
- // Event notification.
- if (cctx.events().isRecordable(EVT_CACHE_OBJECT_UNLOCKED))
- cctx.events().addEvent(partition(), key, doomed.nodeId(), doomed, EVT_CACHE_OBJECT_UNLOCKED,
- val, hasVal, val, hasVal, null, null, null, true);
- }
-
- checkOwnerChanged(prev, owner);
+ checkOwnerChanged(prev, owner, val);
return doomed != null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java
index c5bd71a..8e224c8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/GridLocalLockFuture.java
@@ -231,7 +231,7 @@ public final class GridLocalLockFuture<K, V> extends GridFutureAdapter<Boolean>
!inTx(),
inTx(),
implicitSingle(),
- true
+ false
);
entries.add(entry);
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index c72d7f7..2c02f96 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -53,7 +53,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture;
import org.apache.ignite.internal.processors.cache.GridCacheReturnCompletableWrapper;
import org.apache.ignite.internal.processors.cache.GridCacheSharedManagerAdapter;
import org.apache.ignite.internal.processors.cache.GridDeferredAckMessageSender;
-import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.GridCacheMappedVersion;
import org.apache.ignite.internal.processors.cache.distributed.GridCacheTxFinishSync;
import org.apache.ignite.internal.processors.cache.distributed.GridCacheTxRecoveryFuture;
@@ -105,6 +104,7 @@ import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
import static org.apache.ignite.internal.GridTopic.TOPIC_TX;
import static org.apache.ignite.internal.managers.communication.GridIoPolicy.SYSTEM_POOL;
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.READ;
import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isNearEnabled;
import static org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx.FinalizationStatus.RECOVERY_FINISH;
import static org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx.FinalizationStatus.USER_FINISH;
@@ -1615,7 +1615,9 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
assert serReadVer == null || (tx.optimistic() && tx.serializable()) : txEntry1;
- if (!entry1.tmLock(tx, timeout, serOrder, serReadVer, txEntry1.keepBinary())) {
+ boolean read = serOrder != null && txEntry1.op() == READ;
+
+ if (!entry1.tmLock(tx, timeout, serOrder, serReadVer, read)) {
// Unlock locks locked so far.
for (IgniteTxEntry txEntry2 : entries) {
if (txEntry2 == txEntry1)
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
index 6a73f79..e9be108 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
@@ -590,7 +590,7 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
/**
* @throws Exception If failed.
*/
- public void testTxCommitReadOnlyGetAll(boolean needVer) throws Exception {
+ private void testTxCommitReadOnlyGetAll(boolean needVer) throws Exception {
Ignite ignite0 = ignite(0);
final IgniteTransactions txs = ignite0.transactions();
@@ -925,6 +925,71 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
}
/**
+ * @throws Exception If failed.
+ */
+ public void testTxConflictReadWrite3() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ final IgniteTransactions txs = ignite0.transactions();
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+ List<Integer> readKeys = new ArrayList<>();
+ List<Integer> writeKeys = new ArrayList<>();
+
+ readKeys.add(primaryKey(cache));
+ writeKeys.add(primaryKeys(cache, 1, 1000_0000).get(0));
+
+ if (ccfg.getBackups() > 0) {
+ readKeys.add(backupKey(cache));
+ writeKeys.add(backupKeys(cache, 1, 1000_0000).get(0));
+ }
+
+ if (ccfg.getCacheMode() == PARTITIONED) {
+ readKeys.add(nearKey(cache));
+ writeKeys.add(nearKeys(cache, 1, 1000_0000).get(0));
+ }
+
+ try {
+ for (Integer readKey : readKeys) {
+ for (Integer writeKey : writeKeys) {
+ try {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.get(readKey);
+
+ cache.put(writeKey, writeKey);
+
+ updateKey(cache, readKey, 0);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ // Expected exception.
+ }
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.get(readKey);
+
+ cache.put(writeKey, writeKey);
+
+ tx.commit();
+ }
+ }
+ }
+ }
+ finally {
+ destroyCache(ccfg.getName());
+ }
+ }
+ }
+
+ /**
* @throws Exception If failed
*/
public void testTxConflictGetAndPut1() throws Exception {
@@ -2446,6 +2511,529 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
/**
* @throws Exception If failed.
*/
+ public void testNoReadLockConflict() throws Exception {
+ checkNoReadLockConflict(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testNoReadLockConflictGetEntry() throws Exception {
+ checkNoReadLockConflict(true);
+ }
+
+ /**
+ * @param entry If {@code true} then uses 'getEntry' to read value, otherwise uses 'get'.
+ * @throws Exception If failed.
+ */
+ private void checkNoReadLockConflict(final boolean entry) throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ final AtomicInteger putKey = new AtomicInteger(1_000_000);
+
+ ignite0.createCache(ccfg);
+
+ CacheConfiguration<Integer, Integer> readCacheCcfg = new CacheConfiguration<>(ccfg);
+
+ readCacheCcfg.setName(ccfg.getName() + "-read");
+
+ ignite0.createCache(readCacheCcfg);
+
+ try {
+ checkNoReadLockConflict(ignite(0), ccfg.getName(), ccfg.getName(), entry, putKey);
+
+ checkNoReadLockConflict(ignite(1), ccfg.getName(), ccfg.getName(), entry, putKey);
+
+ checkNoReadLockConflict(ignite(SRVS), ccfg.getName(), ccfg.getName(), entry, putKey);
+
+ checkNoReadLockConflict(ignite(0), readCacheCcfg.getName(), ccfg.getName(), entry, putKey);
+
+ checkNoReadLockConflict(ignite(1), readCacheCcfg.getName(), ccfg.getName(), entry, putKey);
+
+ checkNoReadLockConflict(ignite(SRVS), readCacheCcfg.getName(), ccfg.getName(), entry, putKey);
+ }
+ finally {
+ destroyCache(ccfg.getName());
+
+ destroyCache(readCacheCcfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @param ignite Node.
+ * @param readCacheName Cache name for get.
+ * @param writeCacheName Cache name for put.
+ * @param entry If {@code true} then uses 'getEntry' to read value, otherwise uses 'get'.
+ * @param putKey Write key counter.
+ * @throws Exception If failed.
+ */
+ private void checkNoReadLockConflict(final Ignite ignite,
+ String readCacheName,
+ String writeCacheName,
+ final boolean entry,
+ final AtomicInteger putKey) throws Exception
+ {
+ final int THREADS = 64;
+
+ final IgniteCache<Integer, Integer> readCache = ignite.cache(readCacheName);
+ final IgniteCache<Integer, Integer> writeCache = ignite.cache(writeCacheName);
+
+ List<Integer> readKeys = testKeys(readCache);
+
+ for (final Integer readKey : readKeys) {
+ final CyclicBarrier barrier = new CyclicBarrier(THREADS);
+
+ readCache.put(readKey, Integer.MIN_VALUE);
+
+ GridTestUtils.runMultiThreaded(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ if (entry)
+ readCache.get(readKey);
+ else
+ readCache.getEntry(readKey);
+
+ barrier.await();
+
+ writeCache.put(putKey.incrementAndGet(), 0);
+
+ tx.commit();
+ }
+
+ return null;
+ }
+ }, THREADS, "test-thread");
+
+ assertEquals((Integer)Integer.MIN_VALUE, readCache.get(readKey));
+
+ readCache.put(readKey, readKey);
+
+ assertEquals(readKey, readCache.get(readKey));
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testNoReadLockConflictMultiNode() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ for (final CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ final AtomicInteger putKey = new AtomicInteger(1_000_000);
+
+ ignite0.createCache(ccfg);
+
+ try {
+ final int THREADS = 64;
+
+ IgniteCache<Integer, Integer> cache0 = ignite0.cache(ccfg.getName());
+
+ List<Integer> readKeys = testKeys(cache0);
+
+ for (final Integer readKey : readKeys) {
+ final CyclicBarrier barrier = new CyclicBarrier(THREADS);
+
+ cache0.put(readKey, Integer.MIN_VALUE);
+
+ final AtomicInteger idx = new AtomicInteger();
+
+ GridTestUtils.runMultiThreaded(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ Ignite ignite = ignite(idx.incrementAndGet() % (CLIENTS + SRVS));
+
+ IgniteCache<Integer, Integer> cache = ignite.cache(ccfg.getName());
+
+ try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.get(readKey);
+
+ barrier.await();
+
+ cache.put(putKey.incrementAndGet(), 0);
+
+ tx.commit();
+ }
+
+ return null;
+ }
+ }, THREADS, "test-thread");
+
+ assertEquals((Integer)Integer.MIN_VALUE, cache0.get(readKey));
+
+ cache0.put(readKey, readKey);
+
+ assertEquals(readKey, cache0.get(readKey));
+ }
+ }
+ finally {
+ destroyCache(ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ @SuppressWarnings("UnnecessaryLocalVariable")
+ public void testReadLockPessimisticTxConflict() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ ignite0.createCache(ccfg);
+
+ try {
+ Ignite ignite = ignite0;
+
+ IgniteCache<Integer, Integer> cache = ignite.cache(ccfg.getName());
+
+ Integer writeKey = Integer.MAX_VALUE;
+
+ List<Integer> readKeys = testKeys(cache);
+
+ for (Integer readKey : readKeys) {
+ CountDownLatch latch = new CountDownLatch(1);
+
+ IgniteInternalFuture<?> fut = lockKey(latch, cache, readKey);
+
+ try {
+ // No conflict for write, conflict with pessimistic tx for read.
+ try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.put(writeKey, writeKey);
+
+ cache.get(readKey);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+ finally {
+ latch.countDown();
+ }
+
+ fut.get();
+ }
+ }
+ finally {
+ destroyCache(ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ @SuppressWarnings("UnnecessaryLocalVariable")
+ public void testReadWriteTxConflict() throws Exception {
+ Ignite ignite0 = ignite(0);
+
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ ignite0.createCache(ccfg);
+
+ try {
+ Ignite ignite = ignite0;
+
+ IgniteCache<Integer, Integer> cache = ignite.cache(ccfg.getName());
+
+ Integer writeKey = Integer.MAX_VALUE;
+
+ List<Integer> readKeys = testKeys(cache);
+
+ for (Integer readKey : readKeys) {
+ try {
+ // No conflict for read, conflict for write.
+ try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ cache.getAndPut(writeKey, writeKey);
+
+ cache.get(readKey);
+
+ updateKey(cache, writeKey, writeKey + readKey);
+
+ tx.commit();
+ }
+
+ fail();
+ }
+ catch (TransactionOptimisticException e) {
+ log.info("Expected exception: " + e);
+ }
+
+ assertEquals((Integer)(writeKey + readKey), cache.get(writeKey));
+ assertNull(cache.get(readKey));
+
+ cache.put(readKey, readKey);
+
+ assertEquals(readKey, cache.get(readKey));
+ }
+ }
+ finally {
+ destroyCache(ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testReadWriteTransactionsNoDeadlock() throws Exception {
+ checkReadWriteTransactionsNoDeadlock(false);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testReadWriteTransactionsNoDeadlockMultinode() throws Exception {
+ checkReadWriteTransactionsNoDeadlock(true);
+ }
+
+ /**
+ * @param multiNode Multi-node test flag.
+ * @throws Exception If failed.
+ */
+ private void checkReadWriteTransactionsNoDeadlock(final boolean multiNode) throws Exception {
+ final Ignite ignite0 = ignite(0);
+
+ for (final CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ logCacheInfo(ccfg);
+
+ ignite0.createCache(ccfg);
+
+ try {
+ final long stopTime = U.currentTimeMillis() + 10_000;
+
+ final AtomicInteger idx = new AtomicInteger();
+
+ GridTestUtils.runMultiThreaded(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ Ignite ignite = multiNode ? ignite(idx.incrementAndGet() % (SRVS + CLIENTS)) : ignite0;
+
+ IgniteCache<Integer, Integer> cache = ignite.cache(ccfg.getName());
+
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ while (U.currentTimeMillis() < stopTime) {
+ try {
+ try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+ for (int i = 0; i < 10; i++) {
+ Integer key = rnd.nextInt(30);
+
+ if (rnd.nextBoolean())
+ cache.get(key);
+ else
+ cache.put(key, key);
+ }
+
+ tx.commit();
+ }
+ }
+ catch (TransactionOptimisticException ignore) {
+ // No-op.
+ }
+ }
+
+ return null;
+ }
+ }, 32, "test-thread");
+ }
+ finally {
+ destroyCache(ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testReadWriteAccountTx() throws Exception {
+ final CacheConfiguration<Integer, Integer> ccfg = cacheConfiguration(PARTITIONED,
+ FULL_SYNC,
+ 1,
+ false,
+ false);
+
+ ignite(0).createCache(ccfg);
+
+ try {
+ final int ACCOUNTS = 50;
+ final int VAL_PER_ACCOUNT = 1000;
+
+ IgniteCache<Integer, Account> cache0 = ignite(0).cache(ccfg.getName());
+
+ final Set<Integer> keys = new HashSet<>();
+
+ for (int i = 0; i < ACCOUNTS; i++) {
+ cache0.put(i, new Account(VAL_PER_ACCOUNT));
+
+ keys.add(i);
+ }
+
+ final List<Ignite> clients = clients();
+
+ final AtomicBoolean stop = new AtomicBoolean();
+
+ final AtomicInteger idx = new AtomicInteger();
+
+ IgniteInternalFuture<?> readFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ try {
+ int threadIdx = idx.getAndIncrement();
+
+ int nodeIdx = threadIdx % (SRVS + CLIENTS);
+
+ Ignite node = ignite(nodeIdx);
+
+ IgniteCache<Integer, Account> cache = node.cache(ccfg.getName());
+
+ IgniteTransactions txs = node.transactions();
+
+ Integer putKey = ACCOUNTS + threadIdx;
+
+ while (!stop.get()) {
+ int sum;
+
+ while (true) {
+ sum = 0;
+
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Map<Integer, Account> data = cache.getAll(keys);
+
+ for (int i = 0; i < ACCOUNTS; i++) {
+ Account account = data.get(i);
+
+ assertNotNull(account);
+
+ sum += account.value();
+ }
+
+ cache.put(putKey, new Account(sum));
+
+ tx.commit();
+ }
+ catch (TransactionOptimisticException e) {
+ continue;
+ }
+
+ break;
+ }
+
+ assertEquals(ACCOUNTS * VAL_PER_ACCOUNT, sum);
+ }
+
+ return null;
+ }
+ catch (Throwable e) {
+ stop.set(true);
+
+ log.error("Unexpected error: " + e);
+
+ throw e;
+ }
+ }
+ }, (SRVS + CLIENTS) * 2, "update-thread");
+
+ IgniteInternalFuture<?> updateFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ try {
+ int nodeIdx = idx.getAndIncrement() % clients.size();
+
+ Ignite node = clients.get(nodeIdx);
+
+ IgniteCache<Integer, Account> cache = node.cache(ccfg.getName());
+
+ IgniteTransactions txs = node.transactions();
+
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ while (!stop.get()) {
+ int id1 = rnd.nextInt(ACCOUNTS);
+
+ int id2 = rnd.nextInt(ACCOUNTS);
+
+ while (id2 == id1)
+ id2 = rnd.nextInt(ACCOUNTS);
+
+ while (true) {
+ try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+ Account a1 = cache.get(id1);
+ Account a2 = cache.get(id2);
+
+ assertNotNull(a1);
+ assertNotNull(a2);
+
+ if (a1.value() > 0) {
+ a1 = new Account(a1.value() - 1);
+ a2 = new Account(a2.value() + 1);
+ }
+
+ cache.put(id1, a1);
+ cache.put(id2, a2);
+
+ tx.commit();
+ }
+ catch (TransactionOptimisticException e) {
+ continue;
+ }
+
+ break;
+ }
+ }
+
+ return null;
+ }
+ catch (Throwable e) {
+ stop.set(true);
+
+ log.error("Unexpected error: " + e);
+
+ throw e;
+ }
+ }
+ }, 2, "update-thread");
+
+ try {
+ U.sleep(15_000);
+ }
+ finally {
+ stop.set(true);
+ }
+
+ readFut.get();
+ updateFut.get();
+ int sum = 0;
+
+ for (int i = 0; i < ACCOUNTS; i++) {
+ Account a = cache0.get(i);
+
+ assertNotNull(a);
+ assertTrue(a.value() >= 0);
+
+ log.info("Account: " + a.value());
+
+ sum += a.value();
+ }
+
+ assertEquals(ACCOUNTS * VAL_PER_ACCOUNT, sum);
+ }
+ finally {
+ ignite(0).destroyCache(ccfg.getName());
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testNearCacheReaderUpdate() throws Exception {
Ignite ignite0 = ignite(0);
@@ -4189,13 +4777,17 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
List<Integer> keys = new ArrayList<>();
- if (ccfg.getCacheMode() == PARTITIONED)
- keys.add(nearKey(cache));
+ if (!cache.unwrap(Ignite.class).configuration().isClientMode()) {
+ if (ccfg.getCacheMode() == PARTITIONED)
+ keys.add(nearKey(cache));
- keys.add(primaryKey(cache));
+ keys.add(primaryKey(cache));
- if (ccfg.getBackups() != 0)
- keys.add(backupKey(cache));
+ if (ccfg.getBackups() != 0)
+ keys.add(backupKey(cache));
+ }
+ else
+ keys.add(nearKey(cache));
return keys;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java
index 234f362..ff2d62d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccFlagsTest.java
@@ -82,14 +82,14 @@ public class GridCacheMvccFlagsTest extends GridCommonAbstractTest {
ver,
1,
ver,
- 0,
true,
true,
true,
true,
true,
true,
- null
+ null,
+ false
);
c.setOwner();
@@ -123,14 +123,14 @@ public class GridCacheMvccFlagsTest extends GridCommonAbstractTest {
ver,
1,
ver,
- 0,
false,
false,
false,
false,
false,
false,
- null
+ null,
+ false
);
short flags = c.flags();
http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java
index 1b97663..11a91b5 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccPartitionedSelfTest.java
@@ -29,6 +29,7 @@ import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;
@@ -37,6 +38,9 @@ import static org.apache.ignite.cache.CacheMode.PARTITIONED;
* Test cases for multi-threaded tests in partitioned cache.
*/
public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
+ /** */
+ private static final UUID nodeId = UUID.randomUUID();
+
/** Grid. */
private IgniteKernal grid;
@@ -94,8 +98,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
- GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, 0, false, true);
- GridCacheMvccCandidate c2 = entry.addNearLocal(node1, 1, ver2, 0, true);
+ GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, false, true);
+ GridCacheMvccCandidate c2 = entry.addNearLocal(node1, 1, ver2, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
@@ -128,8 +132,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
- GridCacheMvccCandidate c1 = entry.addNearLocal(node1, 1, ver1, 0, true);
- GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, 0, false, true);
+ GridCacheMvccCandidate c1 = entry.addNearLocal(node1, 1, ver1, true);
+ GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
@@ -161,8 +165,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
- GridCacheMvccCandidate c1 = entry.addNearLocal(node1, 1, ver1, 0, true);
- GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, 0, false, true);
+ GridCacheMvccCandidate c1 = entry.addNearLocal(node1, 1, ver1, true);
+ GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
@@ -194,8 +198,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
- GridCacheMvccCandidate c1 = entry.addNearLocal(node1, 1, ver1, 0, true);
- GridCacheMvccCandidate c2 = entry.addNearLocal(node1, 1, ver2, 0, true);
+ GridCacheMvccCandidate c1 = entry.addNearLocal(node1, 1, ver1, true);
+ GridCacheMvccCandidate c2 = entry.addNearLocal(node1, 1, ver2, true);
entry.readyNearLocal(ver2, ver2, empty(), empty(), empty());
@@ -224,8 +228,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver1 = version(1);
GridCacheVersion ver2 = version(2);
- GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, 0, false, true);
- GridCacheMvccCandidate c2 = entry.addNearLocal(node1, 1, ver2, 0, true);
+ GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, false, true);
+ GridCacheMvccCandidate c2 = entry.addNearLocal(node1, 1, ver2, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
@@ -263,11 +267,11 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver0 = version(0);
GridCacheVersion ver1 = version(1);
- entry.addNearLocal(node1, 1, ver1, 0, true);
+ entry.addNearLocal(node1, 1, ver1, true);
entry.readyNearLocal(ver1, ver1, empty(), empty(), Collections.singletonList(ver0));
- entry.addRemote(node1, 1, ver0, 0, false, true);
+ entry.addRemote(node1, 1, ver0, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
@@ -297,13 +301,13 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver2 = version(2);
GridCacheVersion ver3 = version(3);
- GridCacheMvccCandidate c3 = entry.addNearLocal(node1, 1, ver3, 0, true);
+ GridCacheMvccCandidate c3 = entry.addNearLocal(node1, 1, ver3, true);
entry.readyNearLocal(ver3, ver3, empty(), empty(), Arrays.asList(ver0, ver1, ver2));
- GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, 0, false, true);
- GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, 0, false, true);
- GridCacheMvccCandidate c0 = entry.addRemote(node1, 1, ver0, 0, false, true);
+ GridCacheMvccCandidate c2 = entry.addRemote(node1, 1, ver2, false, true);
+ GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, false, true);
+ GridCacheMvccCandidate c0 = entry.addRemote(node1, 1, ver0, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
@@ -340,13 +344,13 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver2 = version(2);
GridCacheVersion ver3 = version(3);
- GridCacheMvccCandidate c3 = entry.addNearLocal(node1, 1, ver3, 0, true);
- entry.addNearLocal(node1, 1, ver2, 0, true);
+ GridCacheMvccCandidate c3 = entry.addNearLocal(node1, 1, ver3, true);
+ entry.addNearLocal(node1, 1, ver2, true);
entry.readyNearLocal(ver3, ver3, empty(), empty(), Arrays.asList(ver0, ver1, ver2));
- GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, 0, false, true);
- GridCacheMvccCandidate c0 = entry.addRemote(node1, 1, ver0, 0, false, true);
+ GridCacheMvccCandidate c1 = entry.addRemote(node1, 1, ver1, false, true);
+ GridCacheMvccCandidate c0 = entry.addRemote(node1, 1, ver0, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
@@ -386,12 +390,12 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver5 = version(5);
GridCacheVersion ver6 = version(6);
- entry.addRemote(node1, 1, ver1, 0, false, true);
- entry.addRemote(node1, 1, ver2, 0, false, true);
- GridCacheMvccCandidate c3 = entry.addNearLocal(node1, 1, ver3, 0, true);
- GridCacheMvccCandidate c4 = entry.addRemote(node1, 1, ver4, 0, false, true);
- entry.addRemote(node1, 1, ver5, 0, false, true);
- entry.addRemote(node1, 1, ver6, 0, false, true);
+ entry.addRemote(node1, 1, ver1, false, true);
+ entry.addRemote(node1, 1, ver2, false, true);
+ GridCacheMvccCandidate c3 = entry.addNearLocal(node1, 1, ver3, true);
+ GridCacheMvccCandidate c4 = entry.addRemote(node1, 1, ver4, false, true);
+ entry.addRemote(node1, 1, ver5, false, true);
+ entry.addRemote(node1, 1, ver6, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
@@ -442,9 +446,9 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver2 = version(20);
GridCacheVersion ver3 = version(30);
- entry.addRemote(node1, 1, ver1, 0, false, true);
- entry.addNearLocal(node1, 1, nearVer2, 0, true);
- entry.addRemote(node1, 1, ver3, 0, false, true);
+ entry.addRemote(node1, 1, ver1, false, true);
+ entry.addNearLocal(node1, 1, nearVer2, true);
+ entry.addRemote(node1, 1, ver3, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
@@ -480,9 +484,9 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver2 = version(20);
GridCacheVersion ver3 = version(30);
- entry.addRemote(node1, 1, ver1, 0, false, true);
- entry.addNearLocal(node1, 1, nearVer2, 0, true);
- entry.addRemote(node1, 1, ver3, 0, false, true);
+ entry.addRemote(node1, 1, ver1, false, true);
+ entry.addNearLocal(node1, 1, nearVer2, true);
+ entry.addRemote(node1, 1, ver3, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
@@ -525,9 +529,9 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver2 = version(20);
GridCacheVersion ver3 = version(30);
- entry.addRemote(node1, 1, ver1, 0, false, true);
- entry.addNearLocal(node1, 1, nearVer2, 0, true);
- entry.addRemote(node1, 1, ver3, 0, false, true);
+ entry.addRemote(node1, 1, ver1, false, true);
+ entry.addNearLocal(node1, 1, nearVer2, true);
+ entry.addRemote(node1, 1, ver3, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
@@ -570,9 +574,9 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
GridCacheVersion ver2 = version(20);
GridCacheVersion ver3 = version(30);
- entry.addRemote(node1, 1, ver1, 0, false, true);
- entry.addNearLocal(node1, 1, nearVer2, 0, true);
- entry.addRemote(node1, 1, ver3, 0, false, true);
+ entry.addRemote(node1, 1, ver1, false, true);
+ entry.addNearLocal(node1, 1, nearVer2, true);
+ entry.addRemote(node1, 1, ver3, false, true);
Collection<GridCacheMvccCandidate> rmtCands = entry.remoteMvccSnapshot();
Collection<GridCacheMvccCandidate> nearLocCands = entry.localCandidates();
@@ -597,6 +601,222 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
/**
* @throws Exception If failed.
*/
+ public void testSerializableReadLocksAdd() throws Exception {
+ GridCacheAdapter<String, String> cache = grid.internalCache();
+
+ GridCacheVersion serOrder1 = new GridCacheVersion(0, 0, 10, 1);
+ GridCacheVersion serOrder2 = new GridCacheVersion(0, 0, 20, 1);
+ GridCacheVersion serOrder3 = new GridCacheVersion(0, 0, 15, 1);
+
+ {
+ GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
+
+ GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
+
+ GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder1, true);
+
+ assertNotNull(cand1);
+
+ GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder2, true);
+
+ assertNotNull(cand2);
+
+ GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder3, false);
+
+ assertNull(cand3);
+
+ cand3 = addLocal(mvcc, e, version(3), serOrder3, true);
+
+ assertNotNull(cand3);
+ }
+
+ {
+ GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
+
+ GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
+
+ GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder2, true);
+
+ assertNotNull(cand1);
+
+ GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder1, true);
+
+ assertNotNull(cand2);
+
+ GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder3, false);
+
+ assertNull(cand3);
+
+ cand3 = addLocal(mvcc, e, version(3), serOrder3, true);
+
+ assertNotNull(cand3);
+ }
+
+ {
+ GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
+
+ GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
+
+ GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder3, false);
+
+ assertNotNull(cand1);
+
+ GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder2, true);
+
+ assertNotNull(cand2);
+
+ GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder1, true);
+
+ assertNull(cand3);
+
+ cand3 = addLocal(mvcc, e, version(3), serOrder1, false);
+
+ assertNull(cand3);
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testSerializableReadLocksAssign() throws Exception {
+ GridCacheAdapter<String, String> cache = grid.internalCache();
+
+ GridCacheVersion serOrder1 = new GridCacheVersion(0, 0, 10, 1);
+ GridCacheVersion serOrder2 = new GridCacheVersion(0, 0, 20, 1);
+ GridCacheVersion serOrder3 = new GridCacheVersion(0, 0, 15, 1);
+
+ {
+ GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
+
+ GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
+
+ GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder1, true);
+
+ assertNotNull(cand1);
+
+ GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder2, true);
+
+ assertNotNull(cand2);
+
+ GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder3, false);
+
+ assertNull(cand3);
+
+ cand3 = addLocal(mvcc, e, version(3), serOrder3, true);
+
+ assertNotNull(cand3);
+
+ CacheLockCandidates owners = mvcc.recheck();
+
+ assertNull(owners);
+
+ cand1.setReady();
+
+ owners = mvcc.recheck();
+
+ assertSame(cand1, owners);
+ checkCandidates(owners, cand1.version());
+
+ cand2.setReady();
+
+ owners = mvcc.recheck();
+ checkCandidates(owners, cand1.version(), cand2.version());
+
+ mvcc.remove(cand1.version());
+
+ owners = mvcc.recheck();
+ assertSame(cand2, owners);
+ checkCandidates(owners, cand2.version());
+ }
+
+ {
+ GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
+
+ GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
+
+ GridCacheMvccCandidate cand1 = addLocal(mvcc, e, version(1), serOrder1, true);
+
+ assertNotNull(cand1);
+
+ GridCacheMvccCandidate cand2 = addLocal(mvcc, e, version(2), serOrder2, true);
+
+ assertNotNull(cand2);
+
+ GridCacheMvccCandidate cand3 = addLocal(mvcc, e, version(3), serOrder3, false);
+
+ assertNull(cand3);
+
+ cand3 = addLocal(mvcc, e, version(3), serOrder3, true);
+
+ assertNotNull(cand3);
+
+ CacheLockCandidates owners = mvcc.recheck();
+
+ assertNull(owners);
+
+ cand2.setReady();
+
+ owners = mvcc.recheck();
+
+ assertSame(cand2, owners);
+ checkCandidates(owners, cand2.version());
+
+ cand1.setReady();
+
+ owners = mvcc.recheck();
+ checkCandidates(owners, cand1.version(), cand2.version());
+
+ mvcc.remove(cand2.version());
+
+ owners = mvcc.recheck();
+ assertSame(cand1, owners);
+ checkCandidates(owners, cand1.version());
+ }
+ }
+
+ /**
+ * @param all Candidates list.
+ * @param vers Expected candidates.
+ */
+ private void checkCandidates(CacheLockCandidates all, GridCacheVersion...vers) {
+ assertNotNull(all);
+ assertEquals(vers.length, all.size());
+
+ for (GridCacheVersion ver : vers)
+ assertTrue(all.hasCandidate(ver));
+ }
+
+ /**
+ * @param mvcc Mvcc.
+ * @param e Entry.
+ * @param ver Version.
+ * @param serOrder Serializable tx version.
+ * @param read Read lock flag.
+ * @return Candidate.
+ */
+ @Nullable private GridCacheMvccCandidate addLocal(GridCacheMvcc mvcc,
+ GridCacheEntryEx e,
+ GridCacheVersion ver,
+ GridCacheVersion serOrder,
+ boolean read) {
+ return mvcc.addLocal(e,
+ nodeId,
+ null,
+ 1,
+ ver,
+ 0,
+ serOrder,
+ false,
+ true,
+ false,
+ true,
+ read
+ );
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testSerializableLocks() throws Exception {
checkSerializableAdd(false);
@@ -627,7 +847,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
false,
true,
false,
- true
+ true,
+ false
);
assertNotNull(cand1);
@@ -642,7 +863,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
false,
true,
false,
- true
+ true,
+ false
);
assertNull(cand2);
@@ -681,7 +903,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
false,
true,
false,
- true
+ true,
+ false
);
assertNotNull(cand1);
@@ -696,7 +919,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
false,
true,
false,
- true
+ true,
+ false
);
assertNotNull(cand2);
@@ -711,7 +935,8 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
false,
true,
false,
- true
+ true,
+ false
);
assertNull(cand3);
@@ -726,36 +951,37 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
false,
true,
false,
- true
+ true,
+ false
);
assertNotNull(cand4);
- GridCacheMvccCandidate owner = mvcc.recheck();
+ CacheLockCandidates owners = mvcc.recheck();
- assertNull(owner);
+ assertNull(owners);
cand2.setReady();
- owner = mvcc.recheck();
+ owners = mvcc.recheck();
- assertNull(owner);
+ assertNull(owners);
cand1.setReady();
- owner = mvcc.recheck();
+ owners = mvcc.recheck();
- assertSame(cand1, owner);
+ assertSame(cand1, owners);
- owner = mvcc.recheck();
+ owners = mvcc.recheck();
- assertSame(cand1, owner);
+ assertSame(cand1, owners);
mvcc.remove(cand1.version());
- owner = mvcc.recheck();
+ owners = mvcc.recheck();
- assertSame(cand2, owner);
+ assertSame(cand2, owners);
}
/**