Repository: ignite
Updated Branches:
  refs/heads/master abd94fd5d -> d36055ec1


IGNITE-10413 Perform cache validation logic on primary node instead of near 
node - Fixes #5502.

Signed-off-by: Ivan Rakov <[email protected]>


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

Branch: refs/heads/master
Commit: d36055ec16ee52500e4c3b5d23254146cfbf6138
Parents: abd94fd
Author: Slava Koptilin <[email protected]>
Authored: Sat Dec 1 16:00:29 2018 +0300
Committer: Ivan Rakov <[email protected]>
Committed: Sat Dec 1 16:00:29 2018 +0300

----------------------------------------------------------------------
 .../apache/ignite/internal/IgniteKernal.java    |  9 +++--
 .../ignite/internal/IgniteNodeAttributes.java   |  3 ++
 .../distributed/dht/GridDhtTxPrepareFuture.java | 36 +++++++++++++++++
 .../dht/atomic/GridDhtAtomicCache.java          | 41 ++++++++++++++++++--
 .../GridNearAtomicAbstractUpdateRequest.java    |  4 +-
 ...arOptimisticSerializableTxPrepareFuture.java |  3 +-
 .../near/GridNearOptimisticTxPrepareFuture.java |  3 +-
 .../GridNearPessimisticTxPrepareFuture.java     |  3 +-
 .../near/GridNearTxPrepareRequest.java          | 21 +++++++++-
 .../IgniteTxImplicitSingleStateImpl.java        |  5 +++
 .../cache/transactions/IgniteTxLocalState.java  |  5 +++
 .../cache/transactions/IgniteTxStateImpl.java   |  7 +++-
 12 files changed, 126 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java 
b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index faf46cd..4d8a555 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -102,7 +102,6 @@ import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.binary.BinaryUtils;
 import org.apache.ignite.internal.cluster.ClusterGroupAdapter;
 import org.apache.ignite.internal.cluster.IgniteClusterEx;
-import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
 import org.apache.ignite.internal.managers.GridManager;
 import org.apache.ignite.internal.managers.checkpoint.GridCheckpointManager;
 import org.apache.ignite.internal.managers.collision.GridCollisionManager;
@@ -110,6 +109,7 @@ import 
org.apache.ignite.internal.managers.communication.GridIoManager;
 import org.apache.ignite.internal.managers.deployment.GridDeploymentManager;
 import org.apache.ignite.internal.managers.discovery.DiscoveryLocalJoinData;
 import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
+import org.apache.ignite.internal.managers.encryption.GridEncryptionManager;
 import 
org.apache.ignite.internal.managers.eventstorage.GridEventStorageManager;
 import org.apache.ignite.internal.managers.failover.GridFailoverManager;
 import org.apache.ignite.internal.managers.indexing.GridIndexingManager;
@@ -129,8 +129,8 @@ import 
org.apache.ignite.internal.processors.cache.IgniteInternalCache;
 import 
org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
 import org.apache.ignite.internal.processors.cache.mvcc.MvccProcessorImpl;
 import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
-import 
org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
 import 
org.apache.ignite.internal.processors.cache.persistence.DataStorageMXBeanImpl;
+import 
org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
 import 
org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor;
 import 
org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
 import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
@@ -202,9 +202,9 @@ import org.apache.ignite.lifecycle.LifecycleEventType;
 import org.apache.ignite.marshaller.MarshallerExclusions;
 import org.apache.ignite.marshaller.MarshallerUtils;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
-import org.apache.ignite.mxbean.FailureHandlingMxBean;
 import org.apache.ignite.mxbean.ClusterMetricsMXBean;
 import org.apache.ignite.mxbean.DataStorageMXBean;
+import org.apache.ignite.mxbean.FailureHandlingMxBean;
 import org.apache.ignite.mxbean.IgniteMXBean;
 import org.apache.ignite.mxbean.StripedExecutorMXBean;
 import org.apache.ignite.mxbean.ThreadPoolMXBean;
@@ -275,6 +275,7 @@ import static 
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_PORT_RAN
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_SPI_CLASS;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_TX_CONFIG;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_USER_NAME;
+import static 
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_VALIDATE_CACHE_REQUESTS;
 import static org.apache.ignite.internal.IgniteVersionUtils.ACK_VER_STR;
 import static org.apache.ignite.internal.IgniteVersionUtils.BUILD_TSTAMP_STR;
 import static org.apache.ignite.internal.IgniteVersionUtils.COPYRIGHT;
@@ -1566,6 +1567,8 @@ public class IgniteKernal implements IgniteEx, 
IgniteMXBean, Externalizable {
 
         add(ATTR_CONSISTENCY_CHECK_SKIPPED, 
getBoolean(IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK));
 
+        add(ATTR_VALIDATE_CACHE_REQUESTS, Boolean.TRUE);
+
         if (cfg.getConsistentId() != null)
             add(ATTR_NODE_CONSISTENT_ID, cfg.getConsistentId());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java
index 24a71a8..7db7fde 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java
@@ -202,6 +202,9 @@ public final class IgniteNodeAttributes {
     /** Internal attribute name constant. */
     public static final String ATTR_DYNAMIC_CACHE_START_ROLLBACK_SUPPORTED = 
ATTR_PREFIX + ".dynamic.cache.start.rollback.supported";
 
+    /** Internal attribute indicates that incoming cache requests should be 
validated on primary node as well. */
+    public static final String ATTR_VALIDATE_CACHE_REQUESTS = ATTR_CACHE + 
".validate.cache.requests";
+
     /**
      * Enforces singleton.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/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 cc07d77..92e0ce8 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
@@ -97,12 +97,14 @@ import org.apache.ignite.thread.IgniteThread;
 import org.jetbrains.annotations.Nullable;
 
 import static 
org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_OBJECT_LOADED;
+import static 
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_VALIDATE_CACHE_REQUESTS;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheOperation.CREATE;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheOperation.NOOP;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheOperation.READ;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE;
+import static org.apache.ignite.internal.util.lang.GridFunc.isEmpty;
 import static org.apache.ignite.transactions.TransactionState.PREPARED;
 
 /**
@@ -1045,6 +1047,24 @@ public final class GridDhtTxPrepareFuture extends 
GridCacheCompoundFuture<Ignite
 
         this.req = req;
 
+        ClusterNode node = cctx.discovery().node(tx.topologyVersion(), 
tx.nearNodeId());
+
+        boolean validateCache = needCacheValidation(node);
+
+        if (validateCache) {
+            GridDhtTopologyFuture topFut = 
cctx.exchange().lastFinishedFuture();
+
+            if (topFut != null && !isEmpty(req.writes())) {
+                // All caches either read only or not. So validation of one 
cache context is enough.
+                GridCacheContext ctx = F.first(req.writes()).context();
+
+                Throwable err = topFut.validateCache(ctx, req.recovery(), 
isEmpty(req.writes()), null, null);
+
+                if (err != null)
+                    onDone(null, new IgniteCheckedException(err));
+            }
+        }
+
         boolean ser = tx.serializable() && tx.optimistic();
 
         if (!F.isEmpty(req.writes()) || (ser && !F.isEmpty(req.reads()))) {
@@ -1077,6 +1097,22 @@ public final class GridDhtTxPrepareFuture extends 
GridCacheCompoundFuture<Ignite
     }
 
     /**
+     * Returns {@code true} if cache validation needed.
+     *
+     * @param node Originating node.
+     * @return {@code True} if cache should be validated, {@code false} - 
otherwise.
+     */
+    private boolean needCacheValidation(ClusterNode node) {
+        if (node == null) {
+            // The originating (aka near) node has left the topology
+            // and therefore the cache validation doesn't make sense.
+            return false;
+        }
+
+        return 
Boolean.TRUE.equals(node.attribute(ATTR_VALIDATE_CACHE_REQUESTS));
+    }
+
+    /**
      * Checks if this transaction needs previous value for the given tx entry. 
Will use passed in map to store
      * required key or will create new map if passed in map is {@code null}.
      *

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
index 74be8e1..6118fbb 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
@@ -42,7 +42,6 @@ import 
org.apache.ignite.internal.UnregisteredBinaryTypeException;
 import org.apache.ignite.internal.UnregisteredClassException;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.mem.IgniteOutOfMemoryException;
-import 
org.apache.ignite.internal.processors.cache.persistence.StorageException;
 import org.apache.ignite.internal.processors.affinity.AffinityAssignment;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
@@ -69,12 +68,13 @@ import 
org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProce
 import 
org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter;
 import 
org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
 import 
org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtFuture;
-import 
org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException;
-import 
org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology;
+import 
org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
 import 
org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedGetFuture;
 import 
org.apache.ignite.internal.processors.cache.distributed.dht.GridPartitionedSingleGetFuture;
 import 
org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtForceKeysRequest;
 import 
org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtForceKeysResponse;
+import 
org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtInvalidPartitionException;
+import 
org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
@@ -84,6 +84,7 @@ import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearSing
 import 
org.apache.ignite.internal.processors.cache.dr.GridCacheDrExpirationInfo;
 import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo;
 import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
+import 
org.apache.ignite.internal.processors.cache.persistence.StorageException;
 import 
org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalEx;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import 
org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext;
@@ -120,6 +121,7 @@ import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_DEFERRED_AC
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_DEFERRED_ACK_TIMEOUT;
 import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_ASYNC;
 import static 
org.apache.ignite.cache.CacheWriteSynchronizationMode.PRIMARY_SYNC;
+import static 
org.apache.ignite.internal.IgniteNodeAttributes.ATTR_VALIDATE_CACHE_REQUESTS;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
 import static 
org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE;
@@ -1773,11 +1775,31 @@ public class GridDhtAtomicCache<K, V> extends 
GridDhtCacheAdapter<K, V> {
                             if (!req.topologyLocked()) {
                                 // Can not wait for topology future since it 
will break
                                 // GridNearAtomicCheckUpdateRequest processing.
-                                remap = 
!top.topologyVersionFuture().exchangeDone() ||
+                                remap = !top.topologyVersionFuture().isDone() 
||
                                     needRemap(req.topologyVersion(), 
top.readyTopologyVersion(), req.keys());
                             }
 
                             if (!remap) {
+                                boolean validateCache = 
needCacheValidation(node);
+
+                                if (validateCache) {
+                                    GridDhtTopologyFuture topFut = 
top.topologyVersionFuture();
+
+                                    assert topFut.isDone() : topFut;
+
+                                    Throwable err = topFut.validateCache(ctx, 
req.recovery(), false, null, null);
+
+                                    if (err != null) {
+                                        IgniteCheckedException e = new 
IgniteCheckedException(err);
+
+                                        res.error(e);
+
+                                        completionCb.apply(req, res);
+
+                                        return;
+                                    }
+                                }
+
                                 update(node, locked, req, res, updDhtRes);
 
                                 dhtFut = updDhtRes.dhtFuture();
@@ -3636,6 +3658,17 @@ public class GridDhtAtomicCache<K, V> extends 
GridDhtCacheAdapter<K, V> {
         }
     }
 
+    /**
+     * Returns {@code true} if cache validation needed.
+     *
+     * @return {@code True} if cache should be validated, {@code false} - 
otherwise.
+     */
+    private boolean needCacheValidation(ClusterNode node) {
+        assert node != null: "The near node must not be null. This is 
guaranteed by processNearAtomicUpdateRequest()";
+
+        return 
Boolean.TRUE.equals(node.attribute(ATTR_VALIDATE_CACHE_REQUESTS));
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(GridDhtAtomicCache.class, this, super.toString());

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicAbstractUpdateRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicAbstractUpdateRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicAbstractUpdateRequest.java
index 64fe1ee..f0d89bf 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicAbstractUpdateRequest.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicAbstractUpdateRequest.java
@@ -396,14 +396,14 @@ public abstract class GridNearAtomicAbstractUpdateRequest 
extends GridCacheIdMes
     }
 
     /**
-     * @return Keep binary flag.
+     * @return Recovery flag.
      */
     public final boolean recovery() {
         return isFlag(RECOVERY_FLAG_MASK);
     }
 
     /**
-     * @param val Keep binary flag.
+     * @param val Recovery flag.
      */
     public void recovery(boolean val) {
         setFlag(val, RECOVERY_FLAG_MASK);

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
index ef88a6b..2280619 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
@@ -553,7 +553,8 @@ public class GridNearOptimisticSerializableTxPrepareFuture 
extends GridNearOptim
             tx.taskNameHash(),
             m.clientFirst(),
             txNodes.size() == 1,
-            tx.activeCachesDeploymentEnabled());
+            tx.activeCachesDeploymentEnabled(),
+            tx.txState().recovery());
 
         for (IgniteTxEntry txEntry : writes) {
             if (txEntry.op() == TRANSFORM)

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index d47420f..d3639c9 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
@@ -537,7 +537,8 @@ public class GridNearOptimisticTxPrepareFuture extends 
GridNearOptimisticTxPrepa
                     tx.taskNameHash(),
                     m.clientFirst(),
                     true,
-                    tx.activeCachesDeploymentEnabled());
+                    tx.activeCachesDeploymentEnabled(),
+                    tx.txState().recovery());
 
                 for (IgniteTxEntry txEntry : m.entries()) {
                     if (txEntry.op() == TRANSFORM)

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
index 5b6d440..a480a99 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
@@ -223,7 +223,8 @@ public class GridNearPessimisticTxPrepareFuture extends 
GridNearTxPrepareFutureA
             tx.taskNameHash(),
             false,
             true,
-            tx.activeCachesDeploymentEnabled());
+            tx.activeCachesDeploymentEnabled(),
+            tx.txState().recovery());
 
         req.queryUpdate(m.queryUpdate());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
index 87546aa..941c7b3 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
@@ -59,6 +59,9 @@ public class GridNearTxPrepareRequest extends 
GridDistributedTxPrepareRequest {
     /** */
     private static final int ALLOW_WAIT_TOP_FUT_FLAG_MASK = 0x10;
 
+    /** Recovery value flag. */
+    private static final int RECOVERY_FLAG_MASK = 0x40;
+
     /** Future ID. */
     private IgniteUuid futId;
 
@@ -127,7 +130,8 @@ public class GridNearTxPrepareRequest extends 
GridDistributedTxPrepareRequest {
         int taskNameHash,
         boolean firstClientReq,
         boolean allowWaitTopFut,
-        boolean addDepInfo
+        boolean addDepInfo,
+        boolean recovery
     ) {
         super(tx,
             timeout,
@@ -154,6 +158,7 @@ public class GridNearTxPrepareRequest extends 
GridDistributedTxPrepareRequest {
         setFlag(explicitLock, EXPLICIT_LOCK_FLAG_MASK);
         setFlag(firstClientReq, FIRST_CLIENT_REQ_FLAG_MASK);
         setFlag(allowWaitTopFut, ALLOW_WAIT_TOP_FUT_FLAG_MASK);
+        setFlag(recovery, RECOVERY_FLAG_MASK);
     }
 
     /**
@@ -165,6 +170,20 @@ public class GridNearTxPrepareRequest extends 
GridDistributedTxPrepareRequest {
     }
 
     /**
+     * @return Recovery flag.
+     */
+    public final boolean recovery() {
+        return isFlag(RECOVERY_FLAG_MASK);
+    }
+
+    /**
+     * @param val Recovery flag.
+     */
+    public void recovery(boolean val) {
+        setFlag(val, RECOVERY_FLAG_MASK);
+    }
+
+    /**
      * @return {@code True} if first optimistic tx prepare request sent from 
client node.
      */
     public final boolean firstClientRequest() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
index 2b76772..808b7ca 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
@@ -303,6 +303,11 @@ public class IgniteTxImplicitSingleStateImpl extends 
IgniteTxLocalStateAdapter {
     }
 
     /** {@inheritDoc} */
+    @Override public boolean recovery() {
+        return recovery;
+    }
+
+    /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(IgniteTxImplicitSingleStateImpl.class, this);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
index 01eb4f4..e007f90 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
@@ -57,4 +57,9 @@ public interface IgniteTxLocalState extends IgniteTxState {
      * @param partId Partition id.
      */
     public void touchPartition(int cacheId, int partId);
+
+    /**
+     * @return Recovery mode flag.
+     */
+    public boolean recovery();
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d36055ec/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
index cd8c6e9..8a00244 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
@@ -149,7 +149,7 @@ public class IgniteTxStateImpl extends 
IgniteTxLocalStateAdapter {
 
             assert ctx != null : cacheId;
 
-            Throwable err = topFut.validateCache(ctx, recovery != null && 
recovery, read, null, e.getValue());
+            Throwable err = topFut.validateCache(ctx, recovery(), read, null, 
e.getValue());
 
             if (err != null) {
                 if (invalidCaches != null)
@@ -181,6 +181,11 @@ public class IgniteTxStateImpl extends 
IgniteTxLocalStateAdapter {
     }
 
     /** {@inheritDoc} */
+    @Override public boolean recovery() {
+        return recovery != null && recovery;
+    }
+
+    /** {@inheritDoc} */
     @Override public CacheWriteSynchronizationMode 
syncMode(GridCacheSharedContext cctx) {
         CacheWriteSynchronizationMode syncMode = 
CacheWriteSynchronizationMode.FULL_ASYNC;
 

Reply via email to