IEP-12: updated javadoc with notes about data consistency in atomic caches in 
failure scenarios when entry processors and putIfAbsent/replace/remove 
operations are used.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d7987e6d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d7987e6d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d7987e6d

Branch: refs/heads/ignite-zk
Commit: d7987e6d5f633d6d0e4dc8816387efcba7bafbdd
Parents: 0e8224f
Author: yzhdanov <6ufalug04ap>
Authored: Fri Dec 22 15:32:48 2017 +0300
Committer: yzhdanov <6ufalug04ap>
Committed: Fri Dec 22 15:32:48 2017 +0300

----------------------------------------------------------------------
 .../java/org/apache/ignite/IgniteCache.java     | 85 ++++++++++++++++++--
 .../apache/ignite/cache/CacheAtomicityMode.java | 39 ++++++++-
 2 files changed, 115 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d7987e6d/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java 
b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
index 6a0add9..cd8264b 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
@@ -37,6 +37,7 @@ import javax.cache.integration.CacheWriter;
 import javax.cache.processor.EntryProcessor;
 import javax.cache.processor.EntryProcessorException;
 import javax.cache.processor.EntryProcessorResult;
+import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheEntry;
 import org.apache.ignite.cache.CacheEntryProcessor;
 import org.apache.ignite.cache.CacheMetrics;
@@ -556,12 +557,34 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
     public long localSizeLong(int partition, CachePeekMode... peekModes);
 
     /**
+     * Asynchronously invokes each {@link EntryProcessor} from map's values 
against the correspondent
+     * {@link javax.cache.Cache.Entry} specified by map's key set.
+     * <p>
+     * If an {@link javax.cache.Cache.Entry} does not exist for the specified 
key, an attempt is made
+     * to load it (if a loader is configured) or a surrogate {@link 
javax.cache.Cache.Entry},
+     * consisting of the key and a value of null is provided.
+     * <p>
+     * The order that the entries for the keys are processed is undefined.
+     * Implementations may choose to process the entries in any order, 
including
+     * concurrently.  Furthermore there is no guarantee implementations will
+     * use the same {@link EntryProcessor} instance to process each entry, as
+     * the case may be in a non-local cache topology.
+     * <p>
+     * The result of executing the {@link EntryProcessor} is returned in the 
future as a
+     * {@link Map} of {@link EntryProcessorResult}s, one result per key. 
Should the
+     * {@link EntryProcessor} or Caching implementation throw an exception, the
+     * exception is wrapped and re-thrown when a call to
+     * {@link javax.cache.processor.EntryProcessorResult#get()} is made.
+     * <p>
+     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for 
information on
+     * system behavior in crash scenarios for atomic caches.
+     *
      * @param map Map containing keys and entry processors to be applied to 
values.
      * @param args Additional arguments to pass to the {@link EntryProcessor}.
      * @return The map of {@link EntryProcessorResult}s of the processing per 
key,
-     * if any, defined by the {@link EntryProcessor} implementation.  No 
mappings
-     * will be returned for {@link EntryProcessor}s that return a
-     * <code>null</code> value for a key.
+     *      if any, defined by the {@link EntryProcessor} implementation.  No 
mappings
+     *      will be returned for {@link EntryProcessor}s that return a
+     *      <code>null</code> value for a key.
      * @throws TransactionException If operation within transaction is failed.
      */
     @IgniteAsyncSupported
@@ -569,7 +592,7 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
         Object... args) throws TransactionException;
 
     /**
-     * Asynchronously version of the {@link #invokeAll(Set, EntryProcessor, 
Object...)} method.
+     * Asynchronously version of the {@link #invokeAll(Map, Object...)} method.
      *
      * @param map Map containing keys and entry processors to be applied to 
values.
      * @param args Additional arguments to pass to the {@link EntryProcessor}.
@@ -844,6 +867,12 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
 
     /**
      * {@inheritDoc}
+     * <p>
+     * For {@link CacheAtomicityMode#ATOMIC} return
+     * value on primary node crash may be incorrect because of the automatic 
retries. It is recommended
+     * to disable retries with {@link #withNoRetries()} and manually restore 
primary-backup
+     * consistency in case of update failure.
+     *
      * @throws TransactionException If operation within transaction is failed.
      */
     @IgniteAsyncSupported
@@ -852,6 +881,11 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
     /**
      * Asynchronously associates the specified key with the given value if it 
is
      * not already associated with a value.
+     * <p>
+     * For {@link CacheAtomicityMode#ATOMIC} return
+     * value on primary node crash may be incorrect because of the automatic 
retries. It is recommended
+     * to disable retries with {@link #withNoRetries()} and manually restore 
primary-backup
+     * consistency in case of update failure.
      *
      * @param key Key.
      * @param val Value.
@@ -891,6 +925,12 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
 
     /**
      * {@inheritDoc}
+     * <p>
+     * For {@link CacheAtomicityMode#ATOMIC} return
+     * value on primary node crash may be incorrect because of the automatic 
retries. It is recommended
+     * to disable retries with {@link #withNoRetries()} and manually restore 
primary-backup
+     * consistency in case of update failure.
+     *
      * @throws TransactionException If operation within transaction is failed.
      */
     @IgniteAsyncSupported
@@ -899,6 +939,11 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
     /**
      * Asynchronously removes the mapping for a key only if currently mapped 
to the
      * given value.
+     * <p>
+     * For {@link CacheAtomicityMode#ATOMIC} return
+     * value on primary node crash may be incorrect because of the automatic 
retries. It is recommended
+     * to disable retries with {@link #withNoRetries()} and manually restore 
primary-backup
+     * consistency in case of update failure.
      *
      * @param key Key.
      * @param oldVal Old value.
@@ -926,6 +971,12 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
 
     /**
      * {@inheritDoc}
+     * <p>
+     * For {@link CacheAtomicityMode#ATOMIC} return
+     * value on primary node crash may be incorrect because of the automatic 
retries. It is recommended
+     * to disable retries with {@link #withNoRetries()} and manually restore 
primary-backup
+     * consistency in case of update failure.
+     *
      * @throws TransactionException If operation within transaction is failed.
      */
     @IgniteAsyncSupported
@@ -933,6 +984,11 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
 
     /**
      * Asynchronous version of the {@link #replace(Object, Object, Object)}.
+     * <p>
+     * For {@link CacheAtomicityMode#ATOMIC} return
+     * value on primary node crash may be incorrect because of the automatic 
retries. It is recommended
+     * to disable retries with {@link #withNoRetries()} and manually restore 
primary-backup
+     * consistency in case of update failure.
      *
      * @param key Key.
      * @param oldVal Old value.
@@ -1142,16 +1198,24 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
 
     /**
      * {@inheritDoc}
+     * <p>
+     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for 
information on
+     * system behavior in crash scenarios for atomic caches.
+     *
      * @throws TransactionException If operation within transaction is failed.
      */
     @IgniteAsyncSupported
-    @Override public <T> T invoke(K key, EntryProcessor<K, V, T> 
entryProcessor, Object... arguments) throws TransactionException;
+    @Override public <T> T invoke(K key, EntryProcessor<K, V, T> 
entryProcessor, Object... arguments)
+        throws TransactionException;
 
     /**
      * Asynchronously invokes an {@link EntryProcessor} against the {@link 
javax.cache.Cache.Entry} specified by
      * the provided key. If an {@link javax.cache.Cache.Entry} does not exist 
for the specified key,
      * an attempt is made to load it (if a loader is configured) or a surrogate
      * {@link javax.cache.Cache.Entry}, consisting of the key with a null 
value is used instead.
+     * <p>
+     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for 
information on
+     * system behavior in crash scenarios for atomic caches.
      *
      * @param key The key to the entry.
      * @param entryProcessor The {@link EntryProcessor} to invoke.
@@ -1171,6 +1235,9 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
      * An instance of entry processor must be stateless as it may be invoked 
multiple times on primary and
      * backup nodes in the cache. It is guaranteed that the value passed to 
the entry processor will be always
      * the same.
+     * <p>
+     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for 
information on
+     * system behavior in crash scenarios for atomic caches.
      *
      * @param key The key to the entry.
      * @param entryProcessor The {@link CacheEntryProcessor} to invoke.
@@ -1225,6 +1292,10 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
 
     /**
      * {@inheritDoc}
+     * <p>
+     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for 
information on
+     * system behavior in crash scenarios for atomic caches.
+     *
      * @throws TransactionException If operation within transaction is failed.
      */
     @IgniteAsyncSupported
@@ -1250,7 +1321,9 @@ public interface IgniteCache<K, V> extends 
javax.cache.Cache<K, V>, IgniteAsyncS
      * {@link EntryProcessor} or Caching implementation throw an exception, the
      * exception is wrapped and re-thrown when a call to
      * {@link javax.cache.processor.EntryProcessorResult#get()} is made.
-
+     * <p>
+     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for 
information on
+     * system behavior in crash scenarios for atomic caches.
      *
      * @param keys The set of keys.
      * @param entryProcessor The {@link EntryProcessor} to invoke.

http://git-wip-us.apache.org/repos/asf/ignite/blob/d7987e6d/modules/core/src/main/java/org/apache/ignite/cache/CacheAtomicityMode.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/cache/CacheAtomicityMode.java 
b/modules/core/src/main/java/org/apache/ignite/cache/CacheAtomicityMode.java
index 92b5aa1..79a8e5f 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/CacheAtomicityMode.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/CacheAtomicityMode.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.cache;
 
+import javax.cache.processor.EntryProcessor;
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.transactions.Transaction;
 import org.jetbrains.annotations.Nullable;
 
@@ -44,16 +46,47 @@ public enum CacheAtomicityMode {
      * In addition to transactions and locking, one of the main differences in 
{@code ATOMIC} mode
      * is that bulk writes, such as {@code putAll(...)}, {@code 
removeAll(...)}, and {@code transformAll(...)}
      * methods, become simple batch operations which can partially fail. In 
case of partial
-     * failure {@link 
org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException} 
will be thrown
+     * failure {@link CachePartialUpdateException} will be thrown
      * which will contain a list of keys for which the update failed. It is 
recommended that bulk writes are used
      * whenever multiple keys need to be inserted or updated in cache, as they 
reduce number of network trips and
      * provide better performance.
      * <p>
-     * Note that even without locking and transactions, {@code ATOMIC} mode 
still provides
-     * full consistency guarantees across all cache nodes.
+     * Note that even without locking and transactions, {@code ATOMIC} mode 
makes best effort to provide
+     * full consistency guarantees across all cache nodes. However, in 
following scenarios (but not limited to)
+     * full consistency is not possible and {@link #TRANSACTIONAL} mode should 
be used or custom defined recovery
+     * logic should be applied to restore data consistency:
+     * <ul>
+     *     <li>
+     *         Node that originated update has left together with at least one 
primary node
+     *         for this update operation, and left primary node has not 
finished update propagation
+     *         to all nodes holding backup partitions. This way backup copies 
may differ. And also if
+     *         persistent store is configured it may come to an inconsistent 
state as well.
+     *     </li>
+     *     <li>
+     *         If update originating node is alive then update is retried by 
default and for operations
+     *         {@code put(...)}, {@code putAll(...)}, {@code remove(K, V)} and 
{@code removeAll(Set<K>)}
+     *         all copies of partitions will come to a consistent state.
+     *     </li>
+     *     <li>
+     *         If {@link EntryProcessor} is used and processor is not 
idempotent then failure of primary node
+     *         may result in applying the same processor on next chosen 
primary which may have already been
+     *         updated within current operation. If processor is not 
idempotent it is recommended to disable
+     *         automatic retries and manually restore consistency between 
key-value copies in case of update failure.
+     *     </li>
+     *     <li>
+     *         For operations {@code putIfAbsent(K, V)}, {@code replace(K, V, 
V)} and {@code remove(K, V)} return
+     *         value on primary node crash may be incorrect because of the 
automatic retries. It is recommended
+     *         to disable retries with {@link IgniteCache#withNoRetries()} and 
manually restore primary-backup
+     *         consistency in case of update failure.
+     *     </li>
+     * </ul>
      * <p>
      * Also note that all data modifications in {@code ATOMIC} mode are 
guaranteed to be atomic
      * and consistent with writes to the underlying persistent store, if one 
is configured.
+     * <p>
+     * Note! Consistency behavior of atomic cache will be improved in future 
releases.
+     *
+     * @see IgniteCache#withNoRetries()
      */
     ATOMIC;
 

Reply via email to