IGNITE-1988 - Exception for explicit lock inside a transaction
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4d29cb7f Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4d29cb7f Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4d29cb7f Branch: refs/heads/ignite-1282 Commit: 4d29cb7f87aafa505807f4b10cddd0264cdac85f Parents: c23cda1 Author: Valentin Kulichenko <valentin.kuliche...@gmail.com> Authored: Tue Nov 24 16:23:05 2015 -0800 Committer: Valentin Kulichenko <valentin.kuliche...@gmail.com> Committed: Tue Nov 24 16:23:05 2015 -0800 ---------------------------------------------------------------------- .../processors/cache/CacheLockImpl.java | 18 ++++++++- .../colocated/GridDhtColocatedLockFuture.java | 8 ++-- .../cache/GridCacheAbstractFullApiSelfTest.java | 42 +++++++++++++++++++- 3 files changed, 61 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/4d29cb7f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockImpl.java index 2e8dc9b..ae7b42e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockImpl.java @@ -69,6 +69,8 @@ class CacheLockImpl<K, V> implements Lock { CacheOperationContext prev = gate.enter(opCtx); try { + checkTx(); + delegate.lockAll(keys, 0); incrementLockCounter(); @@ -102,6 +104,8 @@ class CacheLockImpl<K, V> implements Lock { CacheOperationContext prev = gate.enter(opCtx); try { + checkTx(); + boolean res = delegate.lockAll(keys, -1); if (res) @@ -128,6 +132,8 @@ class CacheLockImpl<K, V> implements Lock { CacheOperationContext prev = gate.enter(opCtx); try { + checkTx(); + IgniteInternalFuture<Boolean> fut = delegate.lockAllAsync(keys, unit.toMillis(time)); try { @@ -198,8 +204,18 @@ class CacheLockImpl<K, V> implements Lock { throw new UnsupportedOperationException(); } + /** + * Verifies there is no ongoing user transaction. + * + * @throws CacheException + */ + private void checkTx() throws CacheException { + if (delegate.context().tm().inUserTx()) + throw new CacheException("Explicit lock can't be acquired within a transaction."); + } + /** {@inheritDoc} */ @Override public String toString() { return S.toString(CacheLockImpl.class, this); } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/4d29cb7f/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 7e6ce89..ecdf641 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 @@ -296,10 +296,6 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture GridCacheMvccCandidate cand = cctx.mvcc().explicitLock(threadId, txKey); if (inTx()) { - IgniteTxEntry txEntry = tx.entry(txKey); - - txEntry.cached(entry); - if (cand != null) { if (!tx.implicit()) throw new IgniteCheckedException("Cannot access key within transaction if lock is " + @@ -308,6 +304,10 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture return null; } else { + IgniteTxEntry txEntry = tx.entry(txKey); + + txEntry.cached(entry); + // Check transaction entries (corresponding tx entries must be enlisted in transaction). cand = new GridCacheMvccCandidate(entry, cctx.localNodeId(), http://git-wip-us.apache.org/repos/asf/ignite/blob/4d29cb7f/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java index e8e86e9..89c4029 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java @@ -17,8 +17,6 @@ package org.apache.ignite.internal.processors.cache; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -38,6 +36,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import javax.cache.Cache; +import javax.cache.CacheException; import javax.cache.expiry.Duration; import javax.cache.expiry.ExpiryPolicy; import javax.cache.expiry.TouchedExpiryPolicy; @@ -45,6 +44,8 @@ import javax.cache.processor.EntryProcessor; import javax.cache.processor.EntryProcessorException; import javax.cache.processor.EntryProcessorResult; import javax.cache.processor.MutableEntry; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; import junit.framework.AssertionFailedError; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; @@ -5128,6 +5129,43 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract } /** + * @throws Exception If failed. + */ + public void testLockInsideTransaction() throws Exception { + if (txEnabled()) { + GridTestUtils.assertThrows( + log, + new Callable<Object>() { + @Override public Object call() throws Exception { + try (Transaction tx = ignite(0).transactions().txStart()) { + jcache(0).lock("key").lock(); + } + + return null; + } + }, + CacheException.class, + "Explicit lock can't be acquired within a transaction." + ); + + GridTestUtils.assertThrows( + log, + new Callable<Object>() { + @Override public Object call() throws Exception { + try (Transaction tx = ignite(0).transactions().txStart()) { + jcache(0).lockAll(Arrays.asList("key1", "key2")).lock(); + } + + return null; + } + }, + CacheException.class, + "Explicit lock can't be acquired within a transaction." + ); + } + } + + /** * Sets given value, returns old value. */ public static final class SetValueProcessor implements EntryProcessor<String, Integer, Integer> {