# ignite-656 fixes for tx cache
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/f910bb69 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/f910bb69 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/f910bb69 Branch: refs/heads/ignite-80 Commit: f910bb691a3e20ef8f7e28c6cef3e6aa82f94733 Parents: e55cabb Author: sboikov <sboi...@gridgain.com> Authored: Thu Apr 23 12:26:19 2015 +0300 Committer: sboikov <sboi...@gridgain.com> Committed: Thu Apr 23 13:34:30 2015 +0300 ---------------------------------------------------------------------- .../distributed/dht/GridDhtTxPrepareFuture.java | 6 +- .../cache/transactions/IgniteTxEntry.java | 1 + .../transactions/IgniteTxLocalAdapter.java | 10 ++- .../cache/GridCacheAbstractFullApiSelfTest.java | 66 ++++++++++++++------ 4 files changed, 59 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f910bb69/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 2eb79fe..f7b29b5 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 @@ -295,10 +295,14 @@ public final class GridDhtTxPrepareFuture<K, V> extends GridCompoundIdentityFutu if (hasFilters || retVal || txEntry.op() == GridCacheOperation.DELETE) { cached.unswap(retVal); + boolean readThrough = (retVal || hasFilters) && + cacheCtx.config().isLoadPreviousValue() && + !txEntry.skipStore(); + CacheObject val = cached.innerGet( tx, /*swap*/true, - /*read through*/(retVal || hasFilters) && cacheCtx.config().isLoadPreviousValue(), + readThrough, /*fail fast*/false, /*unmarshal*/true, /*metrics*/retVal, http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f910bb69/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java index 43450bd..0d7aeaf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java @@ -314,6 +314,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message { cp.grpLock = grpLock; cp.conflictVer = conflictVer; cp.expiryPlc = expiryPlc; + cp.flags = flags; return cp; } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f910bb69/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java index d93c80e..67609ca 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java @@ -2095,7 +2095,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter CacheObject old = null; - boolean readThrough = !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter); + boolean readThrough = !skipStore && !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter); if (optimistic() && !implicit()) { try { @@ -2390,10 +2390,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter if (retval || invoke) { if (!cacheCtx.isNear()) { try { - if (!hasPrevVal) + if (!hasPrevVal) { + boolean readThrough = + (invoke || cacheCtx.loadPreviousValue()) && !txEntry.skipStore(); + v = cached.innerGet(this, /*swap*/true, - /*read-through*/invoke || cacheCtx.loadPreviousValue(), + readThrough, /*failFast*/false, /*unmarshal*/true, /*metrics*/!invoke, @@ -2403,6 +2406,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter null, resolveTaskName(), null); + } } catch (GridCacheFilterFailedException e) { e.printStackTrace(); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f910bb69/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 59b6b54..ff4a417 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 @@ -4310,11 +4310,13 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract for (String key : keys) assertNull(cache.get(key)); + final int KEYS = 500; + // Put/remove data from multiple nodes. - keys = new ArrayList<>(1000); + keys = new ArrayList<>(KEYS); - for (int i = 0; i < 1000; i++) + for (int i = 0; i < KEYS; i++) keys.add("key_" + i); for (int i = 0; i < keys.size(); ++i) @@ -4392,7 +4394,7 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract // putAll/removeAll from multiple nodes. - Map<String, Integer> data = new HashMap<>(); + Map<String, Integer> data = new LinkedHashMap<>(); for (int i = 0; i < keys.size(); i++) data.put(keys.get(i), i); @@ -4483,29 +4485,14 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract cache.remove(rmvKey); assertTrue(map.size() == 0); - - if (txEnabled()) { - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, OPTIMISTIC,READ_COMMITTED); - - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, OPTIMISTIC, REPEATABLE_READ); - - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, OPTIMISTIC, SERIALIZABLE); - - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, PESSIMISTIC, READ_COMMITTED); - - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, PESSIMISTIC, REPEATABLE_READ); - - checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, PESSIMISTIC, SERIALIZABLE); - } } /** * @throws Exception If failed. */ public void testWithSkipStoreRemoveAll() throws Exception { - if (atomicityMode() == TRANSACTIONAL || - (atomicityMode() == ATOMIC && nearEnabled())) - fail("https://issues.apache.org/jira/browse/IGNITE-373"); + if (atomicityMode() == TRANSACTIONAL || (atomicityMode() == ATOMIC && nearEnabled())) // TODO IGNITE-373. + return; IgniteCache<String, Integer> cache = grid(0).cache(null); @@ -4542,6 +4529,43 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract } /** + * @throws Exception If failed. + */ + public void testWithSkipStoreTx() throws Exception { + if (txEnabled()) { + IgniteCache<String, Integer> cache = grid(0).cache(null); + + IgniteCache<String, Integer> cacheSkipStore = cache.withSkipStore(); + + final int KEYS = 500; + + // Put/remove data from multiple nodes. + + List<String> keys = new ArrayList<>(KEYS); + + for (int i = 0; i < KEYS; i++) + keys.add("key_" + i); + + Map<String, Integer> data = new LinkedHashMap<>(); + + for (int i = 0; i < keys.size(); i++) + data.put(keys.get(i), i); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, OPTIMISTIC, READ_COMMITTED); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, OPTIMISTIC, REPEATABLE_READ); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, OPTIMISTIC, SERIALIZABLE); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, PESSIMISTIC, READ_COMMITTED); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, PESSIMISTIC, REPEATABLE_READ); + + checkSkipStoreWithTransaction(cache, cacheSkipStore, data, keys, PESSIMISTIC, SERIALIZABLE); + } + } + + /** * @param cache Cache instance. * @param cacheSkipStore Cache skip store projection. * @param data Data set. @@ -4559,6 +4583,8 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract TransactionIsolation txIsolation) throws Exception { + log.info("Test tx skip store [concurrency=" + txConcurrency + ", isolation=" + txIsolation + ']'); + cache.removeAll(data.keySet()); checkEmpty(cache, cacheSkipStore);