You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ra...@apache.org on 2015/10/28 13:06:42 UTC

[01/31] ignite git commit: IGNITE-1747 Fix code style and Javadoc issues in MQTT streamer.

Repository: ignite
Updated Branches:
  refs/heads/ignite-1790 1578a243f -> 80bfe09b3


IGNITE-1747 Fix code style and Javadoc issues in MQTT streamer.


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

Branch: refs/heads/ignite-1790
Commit: cb0d432f358615b12a65eb62f4b03b70680b3575
Parents: 43b40f4
Author: Raul Kripalani <ra...@apache.org>
Authored: Tue Oct 20 18:36:52 2015 +0100
Committer: Raul Kripalani <ra...@apache.org>
Committed: Tue Oct 20 18:37:20 2015 +0100

----------------------------------------------------------------------
 .../apache/ignite/stream/mqtt/MqttStreamer.java | 252 +++++++++++++------
 .../stream/mqtt/IgniteMqttStreamerTest.java     |  35 ++-
 .../mqtt/IgniteMqttStreamerTestSuite.java       |   2 +-
 3 files changed, 206 insertions(+), 83 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0d432f/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
index f18ae42..39d8d6e 100644
--- a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
+++ b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.stream.mqtt;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -70,10 +71,10 @@ import org.eclipse.paho.client.mqttv3.MqttMessage;
  * </ul>
  *
  * Note: features like durable subscriptions, last will testament, etc. can be configured via the
- * {@link #connectOptions} property.
+ * {@link #setConnectOptions(MqttConnectOptions)} setter.
  *
  * @see <a href="https://github.com/rholder/guava-retrying">guava-retrying library</a>
- * @author Raul Kripalani
+ *
  */
 public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> implements MqttCallback {
 
@@ -137,7 +138,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     private volatile boolean connected;
 
     /** Cached log prefix for cache messages. */
-    private String cachedLogPrefix;
+    private String cachedLogValues;
 
     /**
      * Starts streamer.
@@ -150,9 +151,12 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
 
         // for simplicity, if these are null initialize to empty lists
         topics = topics == null ? new ArrayList<String>() : topics;
+
         qualitiesOfService = qualitiesOfService == null ? new ArrayList<Integer>() : qualitiesOfService;
 
         try {
+            Map<String, Object> logValues = new HashMap<>();
+
             // parameter validations
             A.notNull(getStreamer(), "streamer");
             A.notNull(getIgnite(), "ignite");
@@ -162,9 +166,8 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
             A.notNullOrEmpty(brokerUrl, "broker URL");
 
             // if the client ID is empty, generate one
-            if (clientId == null || clientId.length() == 0) {
+            if (clientId == null || clientId.length() == 0)
                 clientId = MqttClient.generateClientId();
-            }
 
             // if we have both a single topic and a list of topics (but the list of topic is not of
             // size 1 and == topic, as this would be a case of re-initialization), fail
@@ -174,15 +177,13 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
 
             // same as above but for QoS
             if (qualityOfService != null && !qualitiesOfService.isEmpty() && qualitiesOfService.size() != 1 &&
-                !qualitiesOfService.get(0).equals(qualityOfService)) {
+                !qualitiesOfService.get(0).equals(qualityOfService))
                 throw new IllegalArgumentException("Cannot specify both a single QoS and a list at the same time");
-            }
 
             // Paho API requires disconnect timeout if providing a quiesce timeout and disconnecting forcibly
-            if (disconnectForcibly && disconnectQuiesceTimeout != null) {
+            if (disconnectForcibly && disconnectQuiesceTimeout != null)
                 A.notNull(disconnectForciblyTimeout, "disconnect timeout cannot be null when disconnecting forcibly " +
                     "with quiesce");
-            }
 
             // if we have multiple topics
             if (!topics.isEmpty()) {
@@ -192,7 +193,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
                 A.ensure(qualitiesOfService.isEmpty() || qualitiesOfService.size() == topics.size(), "qualities of " +
                     "service must be either empty or have the same size as topics list");
 
-                cachedLogPrefix = "[" + Joiner.on(",").join(topics) + "]";
+                logValues.put("topics", topics);
             }
             else {  // just the single topic
                 topics.add(topic);
@@ -200,9 +201,16 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
                 if (qualityOfService != null)
                     qualitiesOfService.add(qualityOfService);
 
-                cachedLogPrefix = "[" + topic + "]";
+                logValues.put("topic", topic);
             }
 
+            // finish building log values
+            logValues.put("brokerUrl", brokerUrl);
+            logValues.put("clientId", clientId);
+
+            // cache log values
+            cachedLogValues = "[" + Joiner.on(", ").withKeyValueSeparator("=").join(logValues) + "]";
+
             // create logger
             log = getIgnite().log();
 
@@ -232,6 +240,10 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
 
             // create the connection retrier
             connectionRetrier = new MqttConnectionRetrier(retrier);
+
+            log.info("Starting MQTT Streamer " + cachedLogValues);
+
+            // connect
             connectionRetrier.connect();
 
         }
@@ -286,6 +298,9 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     // -------------------------------
 
     /**
+     * Implements the {@link MqttCallback#connectionLost(Throwable)} callback method for the MQTT client to inform the
+     * streamer that the connection has been lost.
+     *
      * {@inheritDoc}
      */
     @Override public void connectionLost(Throwable throwable) {
@@ -295,31 +310,41 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
         if (stopped)
             return;
 
-        log.warning(String.format("MQTT Connection to server %s was lost.", brokerUrl), throwable);
+        log.warning(String.format("MQTT Connection to broker was lost [brokerUrl=%s, type=%s, err=%s]", brokerUrl,
+            throwable.getClass(), throwable.getMessage()));
+
         connectionRetrier.connect();
     }
 
     /**
+     * Implements the {@link MqttCallback#messageArrived(String, MqttMessage)} to receive an MQTT message.
+     *
      * {@inheritDoc}
      */
     @Override public void messageArrived(String topic, MqttMessage message) throws Exception {
         if (getMultipleTupleExtractor() != null) {
             Map<K, V> entries = getMultipleTupleExtractor().extract(message);
-            if (log.isTraceEnabled()) {
+
+            if (log.isTraceEnabled())
                 log.trace("Adding cache entries: " + entries);
-            }
+
             getStreamer().addData(entries);
         }
         else {
             Map.Entry<K, V> entry = getSingleTupleExtractor().extract(message);
-            if (log.isTraceEnabled()) {
+
+            if (log.isTraceEnabled())
                 log.trace("Adding cache entry: " + entry);
-            }
+
             getStreamer().addData(entry);
         }
     }
 
     /**
+     * Empty implementation of {@link MqttCallback#deliveryComplete(IMqttDeliveryToken)}.
+     *
+     * Not required by the streamer as it doesn't produce messages.
+     *
      * {@inheritDoc}
      */
     @Override public void deliveryComplete(IMqttDeliveryToken token) {
@@ -331,13 +356,8 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     // -------------------------------
 
     /**
-     * @return
-     */
-    public String getBrokerUrl() {
-        return brokerUrl;
-    }
-
-    /**
+     * Sets the broker URL (compulsory).
+     *
      * @param brokerUrl The Broker URL (compulsory).
      */
     public void setBrokerUrl(String brokerUrl) {
@@ -345,189 +365,262 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     }
 
     /**
-     * @return
+     * Gets the broker URL.
+     *
+     * @return The Broker URL.
      */
-    public String getTopic() {
-        return topic;
+    public String getBrokerUrl() {
+        return brokerUrl;
     }
 
     /**
-     * @param topic The topic to subscribe to, if a single topic.
+     * Sets the topic to subscribe to, if a single topic.
+     *
+     * @param topic The topic to subscribe to.
      */
     public void setTopic(String topic) {
         this.topic = topic;
     }
 
     /**
-     * @return
+     * Gets the subscribed topic.
+     *
+     * @return The subscribed topic.
      */
-    public Integer getQualityOfService() {
-        return qualityOfService;
+    public String getTopic() {
+        return topic;
     }
 
     /**
-     * @param qualityOfService The quality of service to use for a single topic subscription (optional).
+     * Sets the quality of service to use for a single topic subscription (optional).
+     *
+     * @param qualityOfService The quality of service.
      */
     public void setQualityOfService(Integer qualityOfService) {
         this.qualityOfService = qualityOfService;
     }
 
     /**
-     * @return
+     * Gets the quality of service set by the user for a single topic consumption.
+     *
+     * @return The quality of service.
      */
-    public List<String> getTopics() {
-        return topics;
+    public Integer getQualityOfService() {
+        return qualityOfService;
     }
 
     /**
-     * @param topics The topics to subscribe to, if many.
+     * Sets the topics to subscribe to, if many.
+     *
+     * @param topics The topics.
      */
     public void setTopics(List<String> topics) {
         this.topics = topics;
     }
 
     /**
-     * @return
+     * Gets the topics subscribed to.
+     *
+     * @return The topics subscribed to.
      */
-    public List<Integer> getQualitiesOfService() {
-        return qualitiesOfService;
+    public List<String> getTopics() {
+        return topics;
     }
 
     /**
-     * @param qualitiesOfService The qualities of service to use for multiple topic subscriptions.
-     * If specified, the list must contain the same number of elements as {@link #topics}.
+     * Sets the qualities of service to use for multiple topic subscriptions. If specified, the list must contain the
+     * same number of elements as {@link #topics}.
+     *
+     * @param qualitiesOfService The qualities of service.
      */
     public void setQualitiesOfService(List<Integer> qualitiesOfService) {
         this.qualitiesOfService = qualitiesOfService;
     }
 
     /**
-     * @return
+     * Gets the qualities of service for multiple topics.
+     *
+     * @return The qualities of service.
      */
-    public String getClientId() {
-        return clientId;
+    public List<Integer> getQualitiesOfService() {
+        return qualitiesOfService;
     }
 
     /**
-     * @param clientId The MQTT client ID (optional). If one is not provided, we'll create one for you and maintain
+     * Sets the MQTT client ID (optional). If one is not provided, the streamer will generate one and will maintain
      * it througout any reconnection attempts.
+     *
+     * @param clientId The client ID.
      */
     public void setClientId(String clientId) {
         this.clientId = clientId;
     }
 
     /**
-     * @return
+     * Gets the client ID, either the one set by the user or the automatically generated one.
+     *
+     * @return The client ID.
+     */
+    public String getClientId() {
+        return clientId;
+    }
+
+    /**
+     * Gets the currently set persistence mechanism.
+     *
+     * @return The persistence mechanism.
      */
     public MqttClientPersistence getPersistence() {
         return persistence;
     }
 
     /**
-     * @param persistence A configurable persistence mechanism. If not set, Paho will use its default.
+     * Sets the persistence mechanism. If not set, Paho will use its default.
+     *
+     * @param persistence A configurable persistence mechanism.
      */
     public void setPersistence(MqttClientPersistence persistence) {
         this.persistence = persistence;
     }
 
     /**
-     * @return
+     * Gets the currently used MQTT client connect options.
+     *
+     * @return The MQTT client connect options.
      */
     public MqttConnectOptions getConnectOptions() {
         return connectOptions;
     }
 
     /**
-     * @param connectOptions The MQTT client connect options, where users can configured the last will and testament, durability, etc.
+     * Sets the MQTT client connect options, where users can configured the last will and testament, durability, etc.
+     *
+     * @param connectOptions The MQTT client connect options.
      */
     public void setConnectOptions(MqttConnectOptions connectOptions) {
         this.connectOptions = connectOptions;
     }
 
     /**
-     * @return
+     * Sets whether to disconnect forcibly or not when shutting down. By default, it's <tt>false</tt>.
+     *
+     * @param disconnectForcibly Whether to disconnect forcibly or not. By default, it's <tt>false</tt>.
+     */
+    public void setDisconnectForcibly(boolean disconnectForcibly) {
+        this.disconnectForcibly = disconnectForcibly;
+    }
+
+    /**
+     * Gets whether this MQTT client will disconnect forcibly when shutting down.
+     *
+     * @return Whether to disconnect forcibly or not.
      */
     public boolean isDisconnectForcibly() {
         return disconnectForcibly;
     }
 
     /**
-     * @param disconnectForcibly Whether to disconnect forcibly or not. By default, it's false.
+     * Sets the quiesce timeout on disconnection. If not provided, this streamer won't use any.
+     *
+     * @param disconnectQuiesceTimeout The disconnect quiesce timeout.
      */
-    public void setDisconnectForcibly(boolean disconnectForcibly) {
-        this.disconnectForcibly = disconnectForcibly;
+    public void setDisconnectQuiesceTimeout(Integer disconnectQuiesceTimeout) {
+        this.disconnectQuiesceTimeout = disconnectQuiesceTimeout;
     }
 
     /**
-     * @return
+     * Gets the disconnect quiesce timeout.
+     *
+     * @return The disconnect quiesce timeout.
      */
     public Integer getDisconnectQuiesceTimeout() {
         return disconnectQuiesceTimeout;
     }
 
     /**
-     * @param disconnectQuiesceTimeout Quiesce timeout on disconnection. If not provided, this streamer won't use any.
+     * Sets the timeout if disconnecting forcibly. Compulsory in that case.
+     *
+     * @param disconnectForciblyTimeout The disconnect forcibly timeout.
      */
-    public void setDisconnectQuiesceTimeout(Integer disconnectQuiesceTimeout) {
-        this.disconnectQuiesceTimeout = disconnectQuiesceTimeout;
+    public void setDisconnectForciblyTimeout(Integer disconnectForciblyTimeout) {
+        this.disconnectForciblyTimeout = disconnectForciblyTimeout;
     }
 
     /**
-     * @return
+     * Gets the timeout if disconnecting forcibly.
+     *
+     * @return Timeout.
      */
     public Integer getDisconnectForciblyTimeout() {
         return disconnectForciblyTimeout;
     }
 
     /**
-     * @param disconnectForciblyTimeout If disconnecting forcibly, the timeout. Compulsory in that case.
+     * Sets the strategy to determine how long to wait between retry attempts. By default, this streamer uses a
+     * Fibonacci-based strategy.
+     *
+     * @param retryWaitStrategy The retry wait strategy.
      */
-    public void setDisconnectForciblyTimeout(Integer disconnectForciblyTimeout) {
-        this.disconnectForciblyTimeout = disconnectForciblyTimeout;
+    public void setRetryWaitStrategy(WaitStrategy retryWaitStrategy) {
+        this.retryWaitStrategy = retryWaitStrategy;
     }
 
     /**
-     * @return
+     * Gets the retry wait strategy.
+     *
+     * @return The retry wait strategy.
      */
     public WaitStrategy getRetryWaitStrategy() {
         return retryWaitStrategy;
     }
 
     /**
-     * @param retryWaitStrategy The strategy to determine how long to wait between retry attempts.
-     * By default, this streamer uses a Fibonacci-based strategy.
+     * Sets the strategy to determine when to stop retrying to (re-)connect. By default, we never stop.
+     *
+     * @param retryStopStrategy The retry stop strategy.
      */
-    public void setRetryWaitStrategy(WaitStrategy retryWaitStrategy) {
-        this.retryWaitStrategy = retryWaitStrategy;
+    public void setRetryStopStrategy(StopStrategy retryStopStrategy) {
+        this.retryStopStrategy = retryStopStrategy;
     }
 
     /**
-     * @return
+     * Gets the retry stop strategy.
+     *
+     * @return The retry stop strategy.
      */
     public StopStrategy getRetryStopStrategy() {
         return retryStopStrategy;
     }
 
     /**
-     * @param retryStopStrategy The strategy to determine when to stop retrying to (re-)connect. By default, we never stop.
+     * Sets whether to block the start() method until connected for the first time. By default, it's <tt>false</tt>.
+     *
+     * @param blockUntilConnected Whether to block or not.
      */
-    public void setRetryStopStrategy(StopStrategy retryStopStrategy) {
-        this.retryStopStrategy = retryStopStrategy;
+    public void setBlockUntilConnected(boolean blockUntilConnected) {
+        this.blockUntilConnected = blockUntilConnected;
     }
 
-    /**
-     * @return
-     */
     public boolean isBlockUntilConnected() {
         return blockUntilConnected;
     }
 
     /**
-     * @param blockUntilConnected Whether to block the start() method until connected for the first time. By default,
-     * false.
+     * Returns whether this streamer is stopped.
+     *
+     * @return <tt>true</tt> if stopped; <tt>false</tt> if not.
      */
-    public void setBlockUntilConnected(boolean blockUntilConnected) {
-        this.blockUntilConnected = blockUntilConnected;
+    public boolean isStopped() {
+        return stopped;
+    }
+
+    /**
+     * Returns whether this streamer is connected.
+     *
+     * @return <tt>true</tt> if connected; <tt>false</tt> if not.
+     */
+    public boolean isConnected() {
+        return connected;
     }
 
     /**
@@ -551,7 +644,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
         }
 
         /**
-         * Method that is called by the streamer to ask us to (re-)connect.
+         * Method called by the streamer to ask us to (re-)connect.
          */
         public void connect() {
             Callable<Boolean> callable = retrier.wrap(new Callable<Boolean>() {
@@ -576,12 +669,15 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
 
                     else {
                         int[] qoses = new int[qualitiesOfService.size()];
+
                         for (int i = 0; i < qualitiesOfService.size(); i++)
                             qoses[i] = qualitiesOfService.get(i);
 
                         client.subscribe(topics.toArray(new String[0]), qoses);
                     }
 
+                    log.info("MQTT Streamer (re-)connected and subscribed " + cachedLogValues);
+
                     connected = true;
                     return connected;
                 }
@@ -608,4 +704,4 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
 
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0d432f/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
index 5ac7339..76404b8 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
@@ -105,6 +105,10 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
         super(true);
     }
 
+    /**
+     *
+     * @throws Exception
+     */
     @Before @SuppressWarnings("unchecked")
     public void beforeTest() throws Exception {
         grid().<Integer, String>getOrCreateCache(defaultCacheConfiguration());
@@ -123,7 +127,9 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
 
         PolicyMap policyMap = new PolicyMap();
         PolicyEntry policy = new PolicyEntry();
+
         policy.setQueuePrefetch(1);
+
         broker.setDestinationPolicy(policyMap);
         broker.getDestinationPolicy().setDefaultEntry(policy);
         broker.setSchedulerSupport(false);
@@ -138,13 +144,19 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
 
         // create the client and connect
         client = new MqttClient(brokerUrl, UUID.randomUUID().toString(), new MemoryPersistence());
+
         client.connect();
 
         // create mqtt streamer
         dataStreamer = grid().dataStreamer(null);
+
         streamer = createMqttStreamer(dataStreamer);
     }
 
+    /**
+     *
+     * @throws Exception
+     */
     @After
     public void afterTest() throws Exception {
         try {
@@ -160,7 +172,6 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
 
         broker.stop();
         broker.deleteAllMessages();
-
     }
 
     /**
@@ -327,7 +338,9 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
         broker.stop();
         broker.start(true);
         broker.waitUntilStarted();
+
         Thread.sleep(2000);
+
         client.connect();
 
         // let's ensure we have 2 connections: Ignite and our test
@@ -370,14 +383,17 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
         // now shutdown the broker, wait 2 seconds and start it again
         broker.stop();
         broker.start(true);
+
         broker.waitUntilStarted();
+
         client.connect();
 
         // lets send messages and ensure they are not received, because our retrier desisted
         sendMessages(Arrays.asList(SINGLE_TOPIC_NAME), 50, 50, false);
+
         Thread.sleep(3000);
-        assertNull(grid().cache(null).get(50));
 
+        assertNull(grid().cache(null).get(50));
     }
 
     /**
@@ -422,8 +438,8 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
         catch (Exception e) {
             return;
         }
-        fail("Expected an exception reporting invalid parameters");
 
+        fail("Expected an exception reporting invalid parameters");
     }
 
     /**
@@ -449,28 +465,34 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     private void sendMessages(final List<String> topics, int fromIdx, int count, boolean singleMessage) throws MqttException {
         if (singleMessage) {
             final List<StringBuilder> sbs = new ArrayList<>(topics.size());
+
             // initialize String Builders for each topic
             F.forEach(topics, new IgniteInClosure<String>() {
                 @Override public void apply(String s) {
                     sbs.add(new StringBuilder());
                 }
             });
+
             // fill String Builders for each topic
             F.forEach(F.range(fromIdx, fromIdx + count), new IgniteInClosure<Integer>() {
                 @Override public void apply(Integer integer) {
                     sbs.get(integer % topics.size()).append(integer.toString() + "," + TEST_DATA.get(integer) + "\n");
                 }
             });
+
             // send each buffer out
             for (int i = 0; i < topics.size(); i++) {
                 MqttMessage msg = new MqttMessage(sbs.get(i).toString().getBytes());
+
                 client.publish(topics.get(i % topics.size()), msg);
             }
         }
         else {
             for (int i = fromIdx; i < fromIdx + count; i++) {
                 byte[] payload = (i + "," + TEST_DATA.get(i)).getBytes();
+
                 MqttMessage msg = new MqttMessage(payload);
+
                 client.publish(topics.get(i % topics.size()), msg);
             }
         }
@@ -487,6 +509,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
         @SuppressWarnings("serial") IgniteBiPredicate<UUID, CacheEvent> callback = new IgniteBiPredicate<UUID, CacheEvent>() {
             @Override public boolean apply(UUID uuid, CacheEvent evt) {
                 latch.countDown();
+
                 return true;
             }
         };
@@ -522,6 +545,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
         return new StreamSingleTupleExtractor<MqttMessage, Integer, String>() {
             @Override public Map.Entry<Integer, String> extract(MqttMessage msg) {
                 List<String> s = Splitter.on(",").splitToList(new String(msg.getPayload()));
+
                 return new GridMapEntry<>(Integer.parseInt(s.get(0)), s.get(1));
             }
         };
@@ -539,15 +563,18 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
                     .omitEmptyStrings()
                     .withKeyValueSeparator(",")
                     .split(new String(msg.getPayload()));
+
                 final Map<Integer, String> answer = new HashMap<>();
+
                 F.forEach(map.keySet(), new IgniteInClosure<String>() {
                     @Override public void apply(String s) {
                         answer.put(Integer.parseInt(s), map.get(s));
                     }
                 });
+
                 return answer;
             }
         };
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/cb0d432f/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
index ff25145..413eaab 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
@@ -31,4 +31,4 @@ import org.junit.runners.Suite;
 })
 public class IgniteMqttStreamerTestSuite {
 
-}
\ No newline at end of file
+}


[12/31] ignite git commit: ignite-1526: IBM JDK is not fully supported by the platfrom. Additional hot fixes.

Posted by ra...@apache.org.
ignite-1526: IBM JDK is not fully supported by the platfrom. Additional hot fixes.


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

Branch: refs/heads/ignite-1790
Commit: e9aa4d101506a6d9bc93dc9133c1d1c5aac0996f
Parents: df931bd
Author: Andrey Gura <ag...@gridgain.com>
Authored: Tue Oct 27 12:52:06 2015 +0300
Committer: Denis Magda <dm...@gridgain.com>
Committed: Tue Oct 27 12:52:06 2015 +0300

----------------------------------------------------------------------
 .../apache/ignite/IgniteSystemProperties.java   |  9 ++++
 .../apache/ignite/internal/IgniteKernal.java    |  2 +
 .../ignite/internal/IgniteNodeAttributes.java   |  3 ++
 .../ignite/internal/util/lang/GridFunc.java     |  8 ++-
 .../optimized/OptimizedMarshaller.java          | 10 +++-
 .../optimized/OptimizedMarshallerUtils.java     | 35 ++++++++++---
 .../ignite/spi/discovery/tcp/ServerImpl.java    | 52 ++++++++++++++++++++
 .../GridDiscoveryManagerAttributesSelfTest.java | 44 +++++++++++++++--
 .../ignite/testframework/GridTestUtils.java     | 19 ++++++-
 9 files changed, 165 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e9aa4d10/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 5d3b08b..1e7d002 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -17,9 +17,11 @@
 
 package org.apache.ignite;
 
+import java.io.Serializable;
 import java.lang.management.RuntimeMXBean;
 import java.util.Properties;
 import javax.net.ssl.HostnameVerifier;
+import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -363,6 +365,13 @@ public final class IgniteSystemProperties {
     public static final String IGNITE_JDBC_DRIVER_CURSOR_REMOVE_DELAY = "IGNITE_JDBC_DRIVER_CURSOR_RMV_DELAY";
 
     /**
+     * Manages {@link OptimizedMarshaller} behavior of {@code serialVersionUID} computation for
+     * {@link Serializable} classes.
+     * */
+    public static final String IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID =
+        "IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID";
+
+    /**
      * Enforces singleton.
      */
     private IgniteSystemProperties() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9aa4d10/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 c02dc59..0865119 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
@@ -200,6 +200,7 @@ import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_JVM_PID;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_LANG_RUNTIME;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MACS;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MARSHALLER;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MARSHALLER_USE_DFLT_SUID;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_NODE_CONSISTENT_ID;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_PEER_CLASSLOADING;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_PHY_RAM;
@@ -1267,6 +1268,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
         add(ATTR_BUILD_VER, VER_STR);
         add(ATTR_BUILD_DATE, BUILD_TSTAMP_STR);
         add(ATTR_MARSHALLER, cfg.getMarshaller().getClass().getName());
+        add(ATTR_MARSHALLER_USE_DFLT_SUID, OptimizedMarshaller.USE_DFLT_SUID);
         add(ATTR_USER_NAME, System.getProperty("user.name"));
         add(ATTR_GRID_NAME, gridName);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9aa4d10/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 10b8df0..b7d2910 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
@@ -34,6 +34,9 @@ public final class IgniteNodeAttributes {
     public static final String ATTR_MARSHALLER = ATTR_PREFIX + ".marshaller";
 
     /** Internal attribute name constant. */
+    public static final String ATTR_MARSHALLER_USE_DFLT_SUID = ATTR_PREFIX + ".marshaller.useDefaultSUID";
+
+    /** Internal attribute name constant. */
     public static final String ATTR_JIT_NAME = ATTR_PREFIX + ".jit.name";
 
     /** Internal attribute name constant. */

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9aa4d10/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
index 43bc5f3..c1d91a8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
@@ -117,6 +117,9 @@ public class GridFunc {
 
     /** */
     private static final IgnitePredicate<Object> ALWAYS_TRUE = new P1<Object>() {
+        /** */
+        private static final long serialVersionUID = 6101914246981105862L;
+
         @Override public boolean apply(Object e) {
             return true;
         }
@@ -1221,9 +1224,10 @@ public class GridFunc {
         if (isEmpty(nodeIds))
             return alwaysFalse();
 
-        assert nodeIds != null;
-
         return new P1<T>() {
+            /** */
+            private static final long serialVersionUID = -5664060422647374863L;
+
             @Override public boolean apply(ClusterNode e) {
                 return nodeIds.contains(e.id());
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9aa4d10/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
index caccd99..b2c98b2 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
@@ -25,6 +25,7 @@ import java.io.Serializable;
 import java.util.concurrent.ConcurrentMap;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.AbstractMarshaller;
@@ -32,8 +33,11 @@ import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 import sun.misc.Unsafe;
 
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
+
 /**
- * Optimized implementation of {@link org.apache.ignite.marshaller.Marshaller}. Unlike {@link org.apache.ignite.marshaller.jdk.JdkMarshaller},
+ * Optimized implementation of {@link org.apache.ignite.marshaller.Marshaller}.
+ * Unlike {@link org.apache.ignite.marshaller.jdk.JdkMarshaller},
  * which is based on standard {@link ObjectOutputStream}, this marshaller does not
  * enforce that all serialized objects implement {@link Serializable} interface. It is also
  * about 20 times faster as it removes lots of serialization overhead that exists in
@@ -80,6 +84,10 @@ import sun.misc.Unsafe;
  * For information about Spring framework visit <a href="http://www.springframework.org/">www.springframework.org</a>
  */
 public class OptimizedMarshaller extends AbstractMarshaller {
+    /** Use default {@code serialVersionUID} for {@link Serializable} classes. */
+    public static final boolean USE_DFLT_SUID =
+        IgniteSystemProperties.getBoolean(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID, false);
+
     /** Default class loader. */
     private final ClassLoader dfltClsLdr = getClass().getClassLoader();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9aa4d10/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
index 584083c..4d6afe6 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.io.ObjectStreamClass;
 import java.io.Serializable;
 import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.nio.charset.Charset;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -42,10 +43,6 @@ class OptimizedMarshallerUtils {
     /** */
     private static final Unsafe UNSAFE = GridUnsafe.unsafe();
 
-    /** Use default {@code serialVersionUid} for {@link Serializable} classes. */
-    private static final boolean USE_DFLT_SUID =
-        Boolean.valueOf(System.getProperty("ignite.marsh.optimized.useDefaultSUID", Boolean.TRUE.toString()));
-
     /** */
     static final long HASH_SET_MAP_OFF;
 
@@ -277,8 +274,8 @@ class OptimizedMarshallerUtils {
     }
 
     /**
-     * Computes the serial version UID value for the given class.
-     * The code is taken from {@link ObjectStreamClass#computeDefaultSUID(Class)}.
+     * Computes the serial version UID value for the given class. The code is taken from {@link
+     * ObjectStreamClass#computeDefaultSUID(Class)}.
      *
      * @param cls A class.
      * @param fields Fields.
@@ -287,8 +284,30 @@ class OptimizedMarshallerUtils {
      */
     @SuppressWarnings("ForLoopReplaceableByForEach")
     static short computeSerialVersionUid(Class cls, List<Field> fields) throws IOException {
-        if (USE_DFLT_SUID && Serializable.class.isAssignableFrom(cls) && !Enum.class.isAssignableFrom(cls))
-            return (short)ObjectStreamClass.lookup(cls).getSerialVersionUID();
+        if (Serializable.class.isAssignableFrom(cls) && !Enum.class.isAssignableFrom(cls)) {
+            try {
+                Field field = cls.getDeclaredField("serialVersionUID");
+
+                if (field.getType() == long.class) {
+                    int mod = field.getModifiers();
+
+                    if (Modifier.isStatic(mod) && Modifier.isFinal(mod)) {
+                        field.setAccessible(true);
+
+                        return (short)field.getLong(null);
+                    }
+                }
+            }
+            catch (NoSuchFieldException e) {
+                // No-op.
+            }
+            catch (IllegalAccessException e) {
+                throw new IOException(e);
+            }
+
+            if (OptimizedMarshaller.USE_DFLT_SUID)
+                return (short)ObjectStreamClass.lookup(cls).getSerialVersionUID();
+        }
 
         MessageDigest md;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9aa4d10/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
index d8ee953..b8df846 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
@@ -126,12 +126,14 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryStatusCheckMessa
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
 import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
 import static org.apache.ignite.events.EventType.EVT_NODE_JOINED;
 import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
 import static org.apache.ignite.events.EventType.EVT_NODE_METRICS_UPDATED;
 import static org.apache.ignite.events.EventType.EVT_NODE_SEGMENTED;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MARSHALLER;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MARSHALLER_USE_DFLT_SUID;
 import static org.apache.ignite.spi.IgnitePortProtocol.TCP;
 import static org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoverySpiState.AUTH_FAILED;
 import static org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoverySpiState.CHECK_FAILED;
@@ -2988,6 +2990,56 @@ class ServerImpl extends TcpDiscoveryImpl {
                     return;
                 }
 
+                // If node have no value for this attribute then we treat it as true.
+                Boolean locMarshUseDfltSuid = locNode.attribute(ATTR_MARSHALLER_USE_DFLT_SUID);
+                boolean locMarshUseDfltSuidBool = locMarshUseDfltSuid == null ? true : locMarshUseDfltSuid;
+
+                Boolean rmtMarshUseDfltSuid = node.attribute(ATTR_MARSHALLER_USE_DFLT_SUID);
+                boolean rmtMarshUseDfltSuidBool = rmtMarshUseDfltSuid == null ? true : rmtMarshUseDfltSuid;
+
+                if (locMarshUseDfltSuidBool != rmtMarshUseDfltSuidBool) {
+                    String errMsg = "Local node's " + IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID +
+                        " property value differs from remote node's value " +
+                        "(to make sure all nodes in topology have identical marshaller settings, " +
+                        "configure system property explicitly) " +
+                        "[locMarshUseDfltSuid=" + locMarshUseDfltSuid + ", rmtMarshUseDfltSuid=" + rmtMarshUseDfltSuid +
+                        ", locNodeAddrs=" + U.addressesAsString(locNode) +
+                        ", rmtNodeAddrs=" + U.addressesAsString(node) +
+                        ", locNodeId=" + locNode.id() + ", rmtNodeId=" + msg.creatorNodeId() + ']';
+
+                    LT.warn(log, null, errMsg);
+
+                    // Always output in debug.
+                    if (log.isDebugEnabled())
+                        log.debug(errMsg);
+
+                    try {
+                        String sndMsg = "Local node's " + IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID +
+                            " property value differs from remote node's value " +
+                            "(to make sure all nodes in topology have identical marshaller settings, " +
+                            "configure system property explicitly) " +
+                            "[locMarshUseDfltSuid=" + locMarshUseDfltSuid +
+                            ", rmtMarshUseDfltSuid=" + rmtMarshUseDfltSuid +
+                            ", locNodeAddrs=" + U.addressesAsString(node) + ", locPort=" + node.discoveryPort() +
+                            ", rmtNodeAddr=" + U.addressesAsString(locNode) + ", locNodeId=" + node.id() +
+                            ", rmtNodeId=" + locNode.id() + ']';
+
+                        trySendMessageDirectly(node,
+                            new TcpDiscoveryCheckFailedMessage(locNodeId, sndMsg));
+                    }
+                    catch (IgniteSpiException e) {
+                        if (log.isDebugEnabled())
+                            log.debug("Failed to send marshaller check failed message to node " +
+                                "[node=" + node + ", err=" + e.getMessage() + ']');
+
+                        onException("Failed to send marshaller check failed message to node " +
+                            "[node=" + node + ", err=" + e.getMessage() + ']', e);
+                    }
+
+                    // Ignore join request.
+                    return;
+                }
+
                 // Handle join.
                 node.internalOrder(ring.nextNodeOrder());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9aa4d10/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java
index dc73cff..6e2c635 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAttributesSelfTest.java
@@ -17,18 +17,15 @@
 
 package org.apache.ignite.internal.managers.discovery;
 
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.DeploymentMode;
 import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteNodeAttributes;
+import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
 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.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 
 import static org.apache.ignite.configuration.DeploymentMode.CONTINUOUS;
@@ -123,6 +120,43 @@ public abstract class GridDiscoveryManagerAttributesSelfTest extends GridCommonA
     /**
      * @throws Exception If failed.
      */
+    public void testUseDefaultSuid() throws Exception {
+        doTestUseDefaultSuid(true, false, true);
+        doTestUseDefaultSuid(false, true, true);
+        doTestUseDefaultSuid(true, true, false);
+        doTestUseDefaultSuid(false, false, false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void doTestUseDefaultSuid(Boolean first, Boolean second, boolean fail) throws Exception {
+        try {
+            GridTestUtils.setFieldValue(null, OptimizedMarshaller.class, "USE_DFLT_SUID", first);
+
+            startGrid(0);
+
+            GridTestUtils.setFieldValue(null, OptimizedMarshaller.class, "USE_DFLT_SUID", second);
+
+            try {
+                startGrid(1);
+
+                if (fail)
+                    fail("Node should not join");
+            }
+            catch (Exception e) {
+                if (!fail)
+                    fail("Node should join");
+            }
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testDifferentDeploymentModes() throws Exception {
         startGrid(0);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9aa4d10/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
index be3f0e4..ea3bbe0 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
@@ -27,6 +27,7 @@ import java.lang.ref.SoftReference;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.net.InetAddress;
 import java.net.MulticastSocket;
 import java.nio.file.attribute.PosixFilePermission;
@@ -1139,7 +1140,6 @@ public final class GridTestUtils {
      */
     @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
     public static void setFieldValue(Object obj, Class cls, String fieldName, Object val) throws IgniteException {
-        assert obj != null;
         assert fieldName != null;
 
         try {
@@ -1149,16 +1149,33 @@ public final class GridTestUtils {
                 // Backup accessible field state.
                 boolean accessible = field.isAccessible();
 
+                boolean isFinal = (field.getModifiers() & Modifier.FINAL) > 0;
+
+                Field modifiersField = null;
+
+                if (isFinal)
+                    modifiersField = Field.class.getDeclaredField("modifiers");
+
                 try {
                     if (!accessible)
                         field.setAccessible(true);
 
+                    if (isFinal) {
+                        modifiersField.setAccessible(true);
+                        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+                    }
+
                     field.set(obj, val);
                 }
                 finally {
                     // Recover accessible field state.
                     if (!accessible)
                         field.setAccessible(false);
+
+                    if (isFinal) {
+                        modifiersField.setInt(field, field.getModifiers() | Modifier.FINAL);
+                        modifiersField.setAccessible(false);
+                    }
                 }
             }
         }


[03/31] ignite git commit: IGNITE-1747 MQTT Streamer: remove 'connected' flag and add 2 tests.

Posted by ra...@apache.org.
IGNITE-1747 MQTT Streamer: remove 'connected' flag and add 2 tests.

MQTT Connection State can be checked by calling MqttClient#isConnected.


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

Branch: refs/heads/ignite-1790
Commit: 0e48722679226a0845ff74dd447f77c2da50ece4
Parents: 056490d
Author: Raul Kripalani <ra...@apache.org>
Authored: Fri Oct 23 17:51:46 2015 +0100
Committer: Raul Kripalani <ra...@apache.org>
Committed: Fri Oct 23 17:51:46 2015 +0100

----------------------------------------------------------------------
 .../apache/ignite/stream/mqtt/MqttStreamer.java | 43 +++++++----------
 .../stream/mqtt/IgniteMqttStreamerTest.java     | 50 +++++++++++++++++++-
 2 files changed, 67 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/0e487226/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
index a075695..e546da2 100644
--- a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
+++ b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
@@ -136,9 +136,6 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     /** State keeping. */
     private volatile boolean stopped = true;
 
-    /** State keeping. */
-    private volatile boolean connected;
-
     /** Cached log prefix for cache messages. */
     private String cachedLogValues;
 
@@ -231,10 +228,10 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
             stopped = false;
 
             // Build retrier.
-            Retryer<Boolean> retrier = RetryerBuilder.<Boolean>newBuilder()
-                .retryIfResult(new Predicate<Boolean>() {
-                    @Override public boolean apply(Boolean connected) {
-                        return !connected;
+            Retryer<Void> retrier = RetryerBuilder.<Void>newBuilder()
+                .retryIfResult(new Predicate<Void>() {
+                    @Override public boolean apply(Void v) {
+                        return !client.isConnected() && !stopped;
                     }
                 })
                 .retryIfException().retryIfRuntimeException()
@@ -288,7 +285,6 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
 
             client.close();
 
-            connected = false;
             stopped = true;
         }
         catch (Exception e) {
@@ -307,9 +303,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
      * {@inheritDoc}
      */
     @Override public void connectionLost(Throwable throwable) {
-        connected = false;
-
-        // if we have been stopped, we do not try to establish the connection again
+        // If we have been stopped, we do not try to establish the connection again.
         if (stopped)
             return;
 
@@ -623,12 +617,13 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     }
 
     /**
-     * Returns whether this streamer is connected.
+     * Returns whether this streamer is connected by delegating to the underlying {@link MqttClient#isConnected()}
      *
      * @return {@code true} if connected; {@code false} if not.
+     * @see MqttClient#isConnected()
      */
     public boolean isConnected() {
-        return connected;
+        return client.isConnected();
     }
 
     /**
@@ -637,17 +632,17 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
      */
     private class MqttConnectionRetrier {
         /** The guava-retrying retrier object. */
-        private final Retryer<Boolean> retrier;
+        private final Retryer<Void> retrier;
 
         /** Single-threaded pool. */
-        private ExecutorService exec = Executors.newSingleThreadExecutor();
+        private final ExecutorService exec = Executors.newSingleThreadExecutor();
 
         /**
          * Constructor.
          *
          * @param retrier The retryier object.
          */
-        public MqttConnectionRetrier(Retryer<Boolean> retrier) {
+        public MqttConnectionRetrier(Retryer<Void> retrier) {
             this.retrier = retrier;
         }
 
@@ -655,14 +650,14 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
          * Method called by the streamer to ask us to (re-)connect.
          */
         public void connect() {
-            Callable<Boolean> callable = retrier.wrap(new Callable<Boolean>() {
-                @Override public Boolean call() throws Exception {
+            Callable<Void> callable = retrier.wrap(new Callable<Void>() {
+                @Override public Void call() throws Exception {
                     // If we're already connected, return immediately.
-                    if (connected)
-                        return true;
+                    if (client.isConnected())
+                        return null;
 
                     if (stopped)
-                        return false;
+                        return null;
 
                     // Connect to broker.
                     if (connectOptions == null)
@@ -686,13 +681,11 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
 
                     log.info("MQTT Streamer (re-)connected and subscribed " + cachedLogValues);
 
-                    connected = true;
-
-                    return true;
+                    return null;
                 }
             });
 
-            Future<Boolean> result = exec.submit(callable);
+            Future<Void> result = exec.submit(callable);
 
             if (blockUntilConnected) {
                 try {

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e487226/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
index 6b07fde..891866d 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
@@ -172,6 +172,54 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     /**
      * @throws Exception If failed.
      */
+    public void testConnectDisconnect() throws Exception {
+        // configure streamer
+        streamer.setSingleTupleExtractor(singleTupleExtractor());
+        streamer.setTopic(SINGLE_TOPIC_NAME);
+        streamer.setBlockUntilConnected(true);
+
+        // action time: repeat 10 times; make sure the connection state is kept correctly every time
+        for (int i = 0; i < 10; i++) {
+            streamer.start();
+
+            assertTrue(streamer.isConnected());
+
+            streamer.stop();
+
+            assertFalse(streamer.isConnected());
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testConnectionStatusWithBrokerDisconnection() throws Exception {
+        // configure streamer
+        streamer.setSingleTupleExtractor(singleTupleExtractor());
+        streamer.setTopic(SINGLE_TOPIC_NAME);
+        streamer.setBlockUntilConnected(true);
+        streamer.setRetryWaitStrategy(WaitStrategies.noWait());
+
+        streamer.start();
+
+        // action time: repeat 5 times; make sure the connection state is kept correctly every time
+        for (int i = 0; i < 5; i++) {
+            assertTrue(streamer.isConnected());
+
+            broker.stop();
+
+            assertFalse(streamer.isConnected());
+
+            broker.start(true);
+            broker.waitUntilStarted();
+
+            Thread.sleep(500);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testSingleTopic_NoQoS_OneEntryPerMessage() throws Exception {
         // configure streamer
         streamer.setSingleTupleExtractor(singleTupleExtractor());
@@ -307,7 +355,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception If failed.
+     * @throws Exception
      */
     public void testSingleTopic_NoQoS_Reconnect() throws Exception {
         // configure streamer


[14/31] ignite git commit: Merge remote-tracking branch 'apache/master'

Posted by ra...@apache.org.
Merge remote-tracking branch 'apache/master'


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

Branch: refs/heads/ignite-1790
Commit: a4d625d0af58437f680b7c136bf7cef72e540303
Parents: b09939f b5a3069
Author: ashutak <as...@gridgain.com>
Authored: Tue Oct 27 14:42:06 2015 +0300
Committer: ashutak <as...@gridgain.com>
Committed: Tue Oct 27 14:42:06 2015 +0300

----------------------------------------------------------------------
 DEVNOTES.txt                                    |   3 +-
 .../apache/ignite/IgniteSystemProperties.java   |   9 +
 .../configuration/CacheConfiguration.java       |  28 ++-
 .../internal/GridEventConsumeHandler.java       |  19 +-
 .../apache/ignite/internal/IgniteKernal.java    |   2 +
 .../ignite/internal/IgniteNodeAttributes.java   |   3 +
 .../deployment/GridDeploymentLocalStore.java    |   8 +-
 .../GridDeploymentPerLoaderStore.java           |   8 +-
 .../GridDeploymentPerVersionStore.java          |   8 +-
 .../internal/portable/PortableContext.java      |  91 +++++---
 .../portable/api/PortableMarshaller.java        |   5 +
 .../processors/cache/CacheObjectContext.java    |  17 +-
 .../processors/cache/GridCacheContext.java      |  10 +-
 .../cache/GridCacheEvictionManager.java         |   5 +-
 .../cache/GridCacheEvictionRequest.java         |  18 +-
 .../cache/GridCacheEvictionResponse.java        |   7 +-
 .../processors/cache/GridCacheIoManager.java    |  34 +--
 .../processors/cache/GridCacheMessage.java      |  72 +++++--
 .../cache/GridCacheSharedContext.java           |   3 +
 .../processors/cache/GridCacheUtils.java        |  20 +-
 .../distributed/GridCacheTtlUpdateRequest.java  |   7 +-
 .../distributed/GridCacheTxRecoveryFuture.java  |   9 +-
 .../distributed/GridCacheTxRecoveryRequest.java |   8 +-
 .../GridCacheTxRecoveryResponse.java            |  10 +-
 .../distributed/GridDistributedBaseMessage.java |  16 +-
 .../distributed/GridDistributedLockRequest.java |   8 +-
 .../GridDistributedLockResponse.java            |  20 +-
 .../GridDistributedTxFinishRequest.java         |   6 +-
 .../GridDistributedTxFinishResponse.java        |   7 +-
 .../GridDistributedTxPrepareRequest.java        |  13 +-
 .../GridDistributedTxPrepareResponse.java       |  12 +-
 .../GridDistributedTxRemoteAdapter.java         |   5 +
 .../GridDistributedUnlockRequest.java           |   7 +-
 .../dht/GridDhtAffinityAssignmentRequest.java   |   7 +-
 .../dht/GridDhtAffinityAssignmentResponse.java  |   7 +-
 .../distributed/dht/GridDhtCacheAdapter.java    |   3 +-
 .../distributed/dht/GridDhtLockFuture.java      |   5 +-
 .../distributed/dht/GridDhtLockRequest.java     |   7 +-
 .../distributed/dht/GridDhtLockResponse.java    |  14 +-
 .../dht/GridDhtTransactionalCacheAdapter.java   |  22 +-
 .../distributed/dht/GridDhtTxFinishFuture.java  |   9 +-
 .../distributed/dht/GridDhtTxFinishRequest.java |   7 +-
 .../dht/GridDhtTxFinishResponse.java            |   2 +-
 .../distributed/dht/GridDhtTxPrepareFuture.java |   9 +-
 .../dht/GridDhtTxPrepareRequest.java            |  28 ++-
 .../dht/GridDhtTxPrepareResponse.java           |  13 +-
 .../distributed/dht/GridDhtUnlockRequest.java   |   7 +-
 .../dht/GridPartitionedGetFuture.java           |   3 +-
 .../dht/atomic/GridDhtAtomicCache.java          |  12 +-
 .../GridDhtAtomicDeferredUpdateResponse.java    |  12 +-
 .../dht/atomic/GridDhtAtomicUpdateFuture.java   |   6 +-
 .../dht/atomic/GridDhtAtomicUpdateRequest.java  |  25 ++-
 .../dht/atomic/GridDhtAtomicUpdateResponse.java |  11 +-
 .../dht/atomic/GridNearAtomicUpdateFuture.java  |  12 +-
 .../dht/atomic/GridNearAtomicUpdateRequest.java |  33 ++-
 .../atomic/GridNearAtomicUpdateResponse.java    |  11 +-
 .../dht/colocated/GridDhtColocatedCache.java    |   8 +-
 .../colocated/GridDhtColocatedLockFuture.java   |   3 +-
 .../dht/preloader/GridDhtForceKeysFuture.java   |   5 +-
 .../dht/preloader/GridDhtForceKeysRequest.java  |  35 ++-
 .../dht/preloader/GridDhtForceKeysResponse.java |  11 +-
 .../GridDhtPartitionDemandMessage.java          |   5 +
 .../GridDhtPartitionSupplyMessage.java          |   9 +-
 .../preloader/GridDhtPartitionSupplyPool.java   |  10 +-
 .../GridDhtPartitionsAbstractMessage.java       |   7 +-
 .../dht/preloader/GridDhtPreloader.java         |   3 +-
 .../distributed/near/GridNearGetFuture.java     |   5 +-
 .../distributed/near/GridNearGetRequest.java    |  12 +-
 .../distributed/near/GridNearGetResponse.java   |  12 +-
 .../distributed/near/GridNearLockFuture.java    |   3 +-
 .../distributed/near/GridNearLockRequest.java   |   8 +-
 .../distributed/near/GridNearLockResponse.java  |   8 +-
 .../near/GridNearOptimisticTxPrepareFuture.java |   3 +-
 .../GridNearPessimisticTxPrepareFuture.java     |   3 +-
 .../near/GridNearTransactionalCache.java        |   8 +-
 .../near/GridNearTxFinishFuture.java            |   8 +-
 .../near/GridNearTxFinishRequest.java           |   7 +-
 .../near/GridNearTxFinishResponse.java          |   2 +-
 .../near/GridNearTxPrepareRequest.java          |   8 +-
 .../near/GridNearTxPrepareResponse.java         |   8 +-
 .../distributed/near/GridNearUnlockRequest.java |   7 +-
 .../portable/CacheObjectPortableContext.java    |   6 +-
 .../CacheObjectPortableProcessorImpl.java       |   5 +-
 .../query/GridCacheDistributedQueryFuture.java  |   5 +-
 .../query/GridCacheDistributedQueryManager.java |  25 ++-
 .../cache/query/GridCacheQueryRequest.java      |  46 ++--
 .../cache/query/GridCacheQueryResponse.java     |  29 ++-
 .../continuous/CacheContinuousQueryHandler.java |   8 +-
 .../continuous/CacheContinuousQueryManager.java |   6 +-
 .../cache/transactions/IgniteInternalTx.java    |   8 +-
 .../cache/transactions/IgniteTxAdapter.java     |   5 +
 .../cache/transactions/IgniteTxEntry.java       |   8 +-
 .../cache/transactions/IgniteTxHandler.java     |  16 +-
 .../transactions/IgniteTxLocalAdapter.java      |  11 +
 .../IgniteCacheObjectProcessorImpl.java         |   7 +-
 .../ignite/internal/util/lang/GridFunc.java     |   8 +-
 .../ignite/marshaller/AbstractMarshaller.java   |  12 +-
 .../ignite/marshaller/jdk/JdkMarshaller.java    |   7 +-
 .../optimized/OptimizedMarshaller.java          |  14 +-
 .../optimized/OptimizedMarshallerUtils.java     |  35 ++-
 .../ignite/spi/discovery/tcp/ServerImpl.java    |  52 +++++
 .../GridDiscoveryManagerAttributesSelfTest.java |  44 +++-
 ...eAtomicEntryProcessorDeploymentSelfTest.java | 211 +++++++++++++++++++
 .../GridCacheConditionalDeploymentSelfTest.java | 190 +++++++++++++++++
 .../GridCacheDeploymentOffHeapSelfTest.java     |  17 +-
 .../cache/GridCacheDeploymentSelfTest.java      |  26 +--
 ...ctionalEntryProcessorDeploymentSelfTest.java |  31 +++
 .../IgniteCacheEntryListenerAbstractTest.java   |  50 ++++-
 .../communication/GridCacheMessageSelfTest.java |  17 +-
 .../ignite/testframework/GridTestUtils.java     |  19 +-
 .../ignite/testsuites/IgniteBasicTestSuite.java |   4 +-
 .../ignite/testsuites/IgniteCacheTestSuite.java |  18 +-
 .../testsuites/IgniteCacheTestSuite3.java       |   8 +-
 .../testsuites/IgniteP2PSelfTestSuite.java      |  16 +-
 .../p2p/CacheDeploymentEntryProcessor.java      |  35 +++
 .../CacheDeploymentPortableEntryProcessor.java  |  35 +++
 modules/spark-2.10/pom.xml                      |   4 +-
 modules/spark/pom.xml                           |   4 +-
 .../ipfinder/zk/ZookeeperIpFinderTestSuite.java |  32 +++
 parent/pom.xml                                  |   1 +
 120 files changed, 1614 insertions(+), 422 deletions(-)
----------------------------------------------------------------------



[21/31] ignite git commit: ignite-1607 Implemented deadlock-free optimistic serializable tx mode

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllSerializableTxBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllSerializableTxBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllSerializableTxBenchmark.java
new file mode 100644
index 0000000..200400e
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllSerializableTxBenchmark.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionOptimisticException;
+import org.yardstickframework.BenchmarkConfiguration;
+
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ *
+ */
+public class IgnitePutAllSerializableTxBenchmark extends IgniteCacheAbstractBenchmark {
+    /** */
+    private IgniteTransactions txs;
+
+    /** {@inheritDoc} */
+    @Override public void setUp(BenchmarkConfiguration cfg) throws Exception {
+        super.setUp(cfg);
+
+        txs = ignite().transactions();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+        ThreadRange r = threadRange();
+
+        Map<Integer, Integer> vals = new HashMap<>();
+
+        for (int i = 0; i < args.batch(); i++) {
+            int key = r.nextRandom();
+
+            vals.put(key, key);
+        }
+
+        while (true) {
+            try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                cache.putAll(vals);
+
+                tx.commit();
+            }
+            catch (TransactionOptimisticException e) {
+                continue;
+            }
+
+            break;
+        }
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Integer, Object> cache() {
+        return ignite().cache("tx");
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/model/Account.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/model/Account.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/model/Account.java
new file mode 100644
index 0000000..3d5d9f8
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/model/Account.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache.model;
+
+import java.io.Serializable;
+
+/**
+ *
+ */
+public class Account implements Serializable {
+    /** */
+    private final int balance;
+
+    /**
+     * @param balance Balance.
+     */
+    public Account(int balance) {
+        this.balance = balance;
+    }
+
+    /**
+     * @return Balance.
+     */
+    public int balance() {
+        return balance;
+    }
+}


[08/31] ignite git commit: ignite-1787 Added synchronization in CacheConfiguration for cache entry listeners collection

Posted by ra...@apache.org.
ignite-1787 Added synchronization in CacheConfiguration for  cache entry listeners collection


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

Branch: refs/heads/ignite-1790
Commit: 18fb46e2bdb5c75dae0d567f1db68bd593aa0355
Parents: 1334e77
Author: sboikov <sb...@gridgain.com>
Authored: Tue Oct 27 12:21:46 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Oct 27 12:21:46 2015 +0300

----------------------------------------------------------------------
 .../configuration/CacheConfiguration.java       | 28 ++++++++++-
 .../IgniteCacheEntryListenerAbstractTest.java   | 50 +++++++++++++++++++-
 2 files changed, 76 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/18fb46e2/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index 6ac2b64..374743f 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -21,6 +21,7 @@ import java.io.Serializable;
 import java.util.Collection;
 import java.util.HashSet;
 import javax.cache.Cache;
+import javax.cache.configuration.CacheEntryListenerConfiguration;
 import javax.cache.configuration.CompleteConfiguration;
 import javax.cache.configuration.Factory;
 import javax.cache.configuration.MutableConfiguration;
@@ -336,7 +337,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         /* No-op. */
     }
 
-    /** Cache name. */
+    /**
+     * @param name Cache name.
+     */
     public CacheConfiguration(String name) {
         this.name = name;
     }
@@ -1800,6 +1803,29 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         return this;
     }
 
+    /** {@inheritDoc} */
+    @Override public Iterable<CacheEntryListenerConfiguration<K, V>> getCacheEntryListenerConfigurations() {
+        synchronized (this) {
+            return new HashSet<>(listenerConfigurations);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public MutableConfiguration<K, V> addCacheEntryListenerConfiguration(
+        CacheEntryListenerConfiguration<K, V> cacheEntryLsnrCfg) {
+        synchronized (this) {
+            return super.addCacheEntryListenerConfiguration(cacheEntryLsnrCfg);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public MutableConfiguration<K, V> removeCacheEntryListenerConfiguration(
+        CacheEntryListenerConfiguration<K, V> cacheEntryLsnrCfg) {
+        synchronized (this) {
+            return super.removeCacheEntryListenerConfiguration(cacheEntryLsnrCfg);
+        }
+    }
+
     /**
      * Creates a copy of current configuration and removes all cache entry listeners.
      * They are executed only locally and should never be sent to remote nodes.

http://git-wip-us.apache.org/repos/asf/ignite/blob/18fb46e2/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheEntryListenerAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheEntryListenerAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheEntryListenerAbstractTest.java
index 3fdd7fc..8a3d756 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheEntryListenerAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheEntryListenerAbstractTest.java
@@ -33,6 +33,7 @@ import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.atomic.AtomicBoolean;
 import javax.cache.configuration.CacheEntryListenerConfiguration;
 import javax.cache.configuration.Factory;
@@ -366,6 +367,42 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
     /**
      * @throws Exception If failed.
      */
+    public void testConcurrentRegisterDeregister() throws Exception {
+        final int THREADS = 10;
+
+        final CyclicBarrier barrier = new CyclicBarrier(THREADS);
+
+        final IgniteCache<Integer, Integer> cache = jcache(0);
+
+        GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
+            @Override public Void call() throws Exception {
+                CacheEntryListenerConfiguration<Integer, Integer> cfg = new MutableCacheEntryListenerConfiguration<>(
+                    new Factory<CacheEntryListener<Integer, Integer>>() {
+                        @Override public CacheEntryListener<Integer, Integer> create() {
+                            return new CreateUpdateRemoveExpireListener();
+                        }
+                    },
+                    null,
+                    true,
+                    false
+                );
+
+                barrier.await();
+
+                for (int i = 0; i < 200; i++) {
+                    cache.registerCacheEntryListener(cfg);
+
+                    cache.deregisterCacheEntryListener(cfg);
+                }
+
+                return null;
+            }
+        }, THREADS, "register-thread").get();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testSerialization() throws Exception {
         if (cacheMode() == LOCAL)
             return;
@@ -951,6 +988,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class CreateUpdateRemoveExpireListenerFactory implements Factory<CacheEntryListener<Integer, Integer>> {
+        /** {@inheritDoc} */
         @Override public CacheEntryListener<Integer, Integer> create() {
             return new CreateUpdateRemoveExpireListener();
         }
@@ -960,6 +998,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class NoOpCreateUpdateListenerFactory implements Factory<CacheEntryListener<Integer, Integer>> {
+        /** {@inheritDoc} */
         @Override public CacheEntryListener<Integer, Integer> create() {
             return new NoOpCreateUpdateListener();
         }
@@ -969,6 +1008,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class CreateUpdateListenerFactory implements Factory<CacheEntryListener<Integer, Integer>> {
+        /** {@inheritDoc} */
         @Override public CacheEntryListener<Integer, Integer> create() {
             return new CreateUpdateListener();
         }
@@ -978,6 +1018,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class CreateListenerFactory implements Factory<CacheEntryListener<Integer, Integer>> {
+        /** {@inheritDoc} */
         @Override public CacheEntryListener<Integer, Integer> create() {
             return new CreateListener();
         }
@@ -987,6 +1028,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class RemoveListenerFactory implements Factory<CacheEntryListener<Integer, Integer>> {
+        /** {@inheritDoc} */
         @Override public CacheEntryListener<Integer, Integer> create() {
             return new RemoveListener();
         }
@@ -996,6 +1038,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class UpdateListenerFactory implements Factory<CacheEntryListener<Integer, Integer>> {
+        /** {@inheritDoc} */
         @Override public CacheEntryListener<Integer, Integer> create() {
             return new UpdateListener();
         }
@@ -1005,6 +1048,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class ExpireListenerFactory implements Factory<CacheEntryListener<Integer, Integer>> {
+        /** {@inheritDoc} */
         @Override public CacheEntryListener<Integer, Integer> create() {
             return new ExpireListener();
         }
@@ -1024,6 +1068,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class CreateListener implements CacheEntryCreatedListener<Integer, Integer> {
+        /** {@inheritDoc} */
         @Override public void onCreated(Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>> evts) {
             for (CacheEntryEvent<? extends Integer, ? extends Integer> evt : evts)
                 onEvent(evt);
@@ -1034,6 +1079,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class UpdateListener implements CacheEntryUpdatedListener<Integer, Integer> {
+        /** {@inheritDoc} */
         @Override public void onUpdated(Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>> evts) {
             for (CacheEntryEvent<? extends Integer, ? extends Integer> evt : evts)
                 onEvent(evt);
@@ -1044,6 +1090,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class RemoveListener implements CacheEntryRemovedListener<Integer, Integer> {
+        /** {@inheritDoc} */
         @Override public void onRemoved(Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>> evts) {
             for (CacheEntryEvent<? extends Integer, ? extends Integer> evt : evts)
                 onEvent(evt);
@@ -1054,6 +1101,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
      *
      */
     private static class ExpireListener implements CacheEntryExpiredListener<Integer, Integer> {
+        /** {@inheritDoc} */
         @Override public void onExpired(Iterable<CacheEntryEvent<? extends Integer, ? extends Integer>> evts) {
             for (CacheEntryEvent<? extends Integer, ? extends Integer> evt : evts)
                 onEvent(evt);
@@ -1238,7 +1286,7 @@ public abstract class IgniteCacheEntryListenerAbstractTest extends IgniteCacheAb
         }
 
         /** {@inheritDoc} */
-        @Override public void onCreated(Iterable<CacheEntryEvent<? extends Object, ? extends Object>> evts)
+        @Override public void onCreated(Iterable<CacheEntryEvent<?, ?>> evts)
             throws CacheEntryListenerException {
             // No-op.
         }


[11/31] ignite git commit: ignite-1272: support of custom class loaders and conditional deployment info for portable marshaller and portable caches

Posted by ra...@apache.org.
ignite-1272: support of custom class loaders and conditional deployment info for portable marshaller and portable caches


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

Branch: refs/heads/ignite-1790
Commit: df931bd09d0a18af839c8d122853111488c1a294
Parents: 18fb46e
Author: Denis Magda <dm...@gridgain.com>
Authored: Tue Oct 27 12:32:02 2015 +0300
Committer: Denis Magda <dm...@gridgain.com>
Committed: Tue Oct 27 12:32:08 2015 +0300

----------------------------------------------------------------------
 .../internal/GridEventConsumeHandler.java       |  19 +-
 .../deployment/GridDeploymentLocalStore.java    |   8 +-
 .../GridDeploymentPerLoaderStore.java           |   8 +-
 .../GridDeploymentPerVersionStore.java          |   8 +-
 .../internal/portable/PortableContext.java      |  91 +++++---
 .../portable/api/PortableMarshaller.java        |   5 +
 .../processors/cache/CacheObjectContext.java    |  17 +-
 .../processors/cache/GridCacheContext.java      |  10 +-
 .../cache/GridCacheEvictionManager.java         |   5 +-
 .../cache/GridCacheEvictionRequest.java         |  18 +-
 .../cache/GridCacheEvictionResponse.java        |   7 +-
 .../processors/cache/GridCacheIoManager.java    |  34 +--
 .../processors/cache/GridCacheMessage.java      |  72 +++++--
 .../cache/GridCacheSharedContext.java           |   3 +
 .../processors/cache/GridCacheUtils.java        |  20 +-
 .../distributed/GridCacheTtlUpdateRequest.java  |   7 +-
 .../distributed/GridCacheTxRecoveryFuture.java  |   9 +-
 .../distributed/GridCacheTxRecoveryRequest.java |   8 +-
 .../GridCacheTxRecoveryResponse.java            |  10 +-
 .../distributed/GridDistributedBaseMessage.java |  16 +-
 .../distributed/GridDistributedLockRequest.java |   8 +-
 .../GridDistributedLockResponse.java            |  20 +-
 .../GridDistributedTxFinishRequest.java         |   6 +-
 .../GridDistributedTxFinishResponse.java        |   7 +-
 .../GridDistributedTxPrepareRequest.java        |  13 +-
 .../GridDistributedTxPrepareResponse.java       |  12 +-
 .../GridDistributedTxRemoteAdapter.java         |   5 +
 .../GridDistributedUnlockRequest.java           |   7 +-
 .../dht/GridDhtAffinityAssignmentRequest.java   |   7 +-
 .../dht/GridDhtAffinityAssignmentResponse.java  |   7 +-
 .../distributed/dht/GridDhtCacheAdapter.java    |   3 +-
 .../distributed/dht/GridDhtLockFuture.java      |   5 +-
 .../distributed/dht/GridDhtLockRequest.java     |   7 +-
 .../distributed/dht/GridDhtLockResponse.java    |  14 +-
 .../dht/GridDhtTransactionalCacheAdapter.java   |  22 +-
 .../distributed/dht/GridDhtTxFinishFuture.java  |   9 +-
 .../distributed/dht/GridDhtTxFinishRequest.java |   7 +-
 .../dht/GridDhtTxFinishResponse.java            |   2 +-
 .../distributed/dht/GridDhtTxPrepareFuture.java |   9 +-
 .../dht/GridDhtTxPrepareRequest.java            |  28 ++-
 .../dht/GridDhtTxPrepareResponse.java           |  13 +-
 .../distributed/dht/GridDhtUnlockRequest.java   |   7 +-
 .../dht/GridPartitionedGetFuture.java           |   3 +-
 .../dht/atomic/GridDhtAtomicCache.java          |  12 +-
 .../GridDhtAtomicDeferredUpdateResponse.java    |  12 +-
 .../dht/atomic/GridDhtAtomicUpdateFuture.java   |   6 +-
 .../dht/atomic/GridDhtAtomicUpdateRequest.java  |  25 ++-
 .../dht/atomic/GridDhtAtomicUpdateResponse.java |  11 +-
 .../dht/atomic/GridNearAtomicUpdateFuture.java  |  12 +-
 .../dht/atomic/GridNearAtomicUpdateRequest.java |  33 ++-
 .../atomic/GridNearAtomicUpdateResponse.java    |  11 +-
 .../dht/colocated/GridDhtColocatedCache.java    |   8 +-
 .../colocated/GridDhtColocatedLockFuture.java   |   3 +-
 .../dht/preloader/GridDhtForceKeysFuture.java   |   5 +-
 .../dht/preloader/GridDhtForceKeysRequest.java  |  35 ++-
 .../dht/preloader/GridDhtForceKeysResponse.java |  11 +-
 .../GridDhtPartitionDemandMessage.java          |   5 +
 .../GridDhtPartitionSupplyMessage.java          |   9 +-
 .../preloader/GridDhtPartitionSupplyPool.java   |  10 +-
 .../GridDhtPartitionsAbstractMessage.java       |   7 +-
 .../dht/preloader/GridDhtPreloader.java         |   3 +-
 .../distributed/near/GridNearGetFuture.java     |   5 +-
 .../distributed/near/GridNearGetRequest.java    |  12 +-
 .../distributed/near/GridNearGetResponse.java   |  12 +-
 .../distributed/near/GridNearLockFuture.java    |   3 +-
 .../distributed/near/GridNearLockRequest.java   |   8 +-
 .../distributed/near/GridNearLockResponse.java  |   8 +-
 .../near/GridNearOptimisticTxPrepareFuture.java |   3 +-
 .../GridNearPessimisticTxPrepareFuture.java     |   3 +-
 .../near/GridNearTransactionalCache.java        |   8 +-
 .../near/GridNearTxFinishFuture.java            |   8 +-
 .../near/GridNearTxFinishRequest.java           |   7 +-
 .../near/GridNearTxFinishResponse.java          |   2 +-
 .../near/GridNearTxPrepareRequest.java          |   8 +-
 .../near/GridNearTxPrepareResponse.java         |   8 +-
 .../distributed/near/GridNearUnlockRequest.java |   7 +-
 .../portable/CacheObjectPortableContext.java    |   6 +-
 .../CacheObjectPortableProcessorImpl.java       |   5 +-
 .../query/GridCacheDistributedQueryFuture.java  |   5 +-
 .../query/GridCacheDistributedQueryManager.java |  25 ++-
 .../cache/query/GridCacheQueryRequest.java      |  46 ++--
 .../cache/query/GridCacheQueryResponse.java     |  29 ++-
 .../continuous/CacheContinuousQueryHandler.java |   8 +-
 .../cache/transactions/IgniteInternalTx.java    |   8 +-
 .../cache/transactions/IgniteTxAdapter.java     |   5 +
 .../cache/transactions/IgniteTxEntry.java       |   8 +-
 .../cache/transactions/IgniteTxHandler.java     |  16 +-
 .../transactions/IgniteTxLocalAdapter.java      |  11 +
 .../IgniteCacheObjectProcessorImpl.java         |   7 +-
 .../ignite/marshaller/AbstractMarshaller.java   |  12 +-
 .../ignite/marshaller/jdk/JdkMarshaller.java    |   7 +-
 .../optimized/OptimizedMarshaller.java          |   4 +-
 ...eAtomicEntryProcessorDeploymentSelfTest.java | 211 +++++++++++++++++++
 .../GridCacheConditionalDeploymentSelfTest.java | 190 +++++++++++++++++
 .../GridCacheDeploymentOffHeapSelfTest.java     |  17 +-
 .../cache/GridCacheDeploymentSelfTest.java      |  26 +--
 ...ctionalEntryProcessorDeploymentSelfTest.java |  31 +++
 .../communication/GridCacheMessageSelfTest.java |  17 +-
 .../ignite/testsuites/IgniteBasicTestSuite.java |   4 +-
 .../ignite/testsuites/IgniteCacheTestSuite.java |  18 +-
 .../testsuites/IgniteCacheTestSuite3.java       |   8 +-
 .../testsuites/IgniteP2PSelfTestSuite.java      |  16 +-
 .../p2p/CacheDeploymentEntryProcessor.java      |  35 +++
 .../CacheDeploymentPortableEntryProcessor.java  |  35 +++
 104 files changed, 1332 insertions(+), 394 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
index 599d301..b4ce4ab 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridEventConsumeHandler.java
@@ -35,6 +35,7 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo;
 import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean;
 import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
 import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheDeployable;
 import org.apache.ignite.internal.processors.cache.GridCacheDeploymentManager;
 import org.apache.ignite.internal.processors.continuous.GridContinuousHandler;
@@ -197,16 +198,18 @@ class GridEventConsumeHandler implements GridContinuousHandler {
                                                     if (node == null)
                                                         continue;
 
-                                                    if (ctx.config().isPeerClassLoadingEnabled()
-                                                        && ctx.discovery().cacheNode(node, cacheName)) {
-                                                        wrapper.p2pMarshal(ctx.config().getMarshaller());
+                                                    if (ctx.config().isPeerClassLoadingEnabled()) {
+                                                        GridCacheContext cctx =
+                                                            ctx.cache().internalCache(cacheName).context();
 
-                                                        wrapper.cacheName = cacheName;
+                                                        if (cctx.deploymentEnabled() &&
+                                                            ctx.discovery().cacheNode(node, cacheName)) {
+                                                            wrapper.p2pMarshal(ctx.config().getMarshaller());
 
-                                                        GridCacheDeploymentManager depMgr = ctx.cache()
-                                                            .internalCache(cacheName).context().deploy();
+                                                            wrapper.cacheName = cacheName;
 
-                                                        depMgr.prepare(wrapper);
+                                                            cctx.deploy().prepare(wrapper);
+                                                        }
                                                     }
                                                 }
 
@@ -519,4 +522,4 @@ class GridEventConsumeHandler implements GridContinuousHandler {
                 evt = (Event)in.readObject();
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
index 420eea8..d095efb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
@@ -39,7 +39,7 @@ import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.marshaller.AbstractMarshaller;
 import org.apache.ignite.spi.IgniteSpiException;
 import org.apache.ignite.spi.deployment.DeploymentListener;
 import org.apache.ignite.spi.deployment.DeploymentResource;
@@ -541,8 +541,8 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
                 ctx.resource().onUndeployed(dep);
 
                 // Clear optimized marshaller's cache.
-                if (ctx.config().getMarshaller() instanceof OptimizedMarshaller)
-                    ((OptimizedMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr);
+                if (ctx.config().getMarshaller() instanceof AbstractMarshaller)
+                    ((AbstractMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr);
 
                 clearSerializationCaches();
 
@@ -572,4 +572,4 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
             undeploy(ldr);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
index 6ca74eb..4ba308c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
@@ -39,7 +39,7 @@ import org.apache.ignite.internal.util.GridClassLoaderCache;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.marshaller.AbstractMarshaller;
 import org.apache.ignite.spi.deployment.DeploymentSpi;
 
 import static org.apache.ignite.events.EventType.EVT_CLASS_DEPLOYED;
@@ -511,8 +511,8 @@ public class GridDeploymentPerLoaderStore extends GridDeploymentStoreAdapter {
                 ctx.cache().onUndeployed(ldr);
 
                 // Clear optimized marshaller's cache.
-                if (ctx.config().getMarshaller() instanceof OptimizedMarshaller)
-                    ((OptimizedMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr);
+                if (ctx.config().getMarshaller() instanceof AbstractMarshaller)
+                    ((AbstractMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr);
 
                 clearSerializationCaches();
 
@@ -527,4 +527,4 @@ public class GridDeploymentPerLoaderStore extends GridDeploymentStoreAdapter {
             return S.toString(IsolatedDeployment.class, this, super.toString());
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java
index 6f9e968..fabbcb2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java
@@ -46,7 +46,7 @@ import org.apache.ignite.internal.util.typedef.internal.LT;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.marshaller.AbstractMarshaller;
 import org.apache.ignite.spi.deployment.DeploymentSpi;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
@@ -1281,8 +1281,8 @@ public class GridDeploymentPerVersionStore extends GridDeploymentStoreAdapter {
                 ctx.cache().onUndeployed(ldr);
 
                 // Clear optimized marshaller's cache.
-                if (ctx.config().getMarshaller() instanceof OptimizedMarshaller)
-                    ((OptimizedMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr);
+                if (ctx.config().getMarshaller() instanceof AbstractMarshaller)
+                    ((AbstractMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr);
 
                 clearSerializationCaches();
 
@@ -1297,4 +1297,4 @@ public class GridDeploymentPerVersionStore extends GridDeploymentStoreAdapter {
             return S.toString(SharedDeployment.class, this, "super", super.toString());
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
index e9cccf0..acd6a56 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
@@ -52,24 +52,25 @@ import java.util.jar.JarFile;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.IgnitionEx;
+import org.apache.ignite.internal.portable.api.PortableException;
+import org.apache.ignite.internal.portable.api.PortableIdMapper;
+import org.apache.ignite.internal.portable.api.PortableInvalidClassException;
+import org.apache.ignite.internal.portable.api.PortableMarshaller;
+import org.apache.ignite.internal.portable.api.PortableMetadata;
+import org.apache.ignite.internal.portable.api.PortableSerializer;
+import org.apache.ignite.internal.portable.api.PortableTypeConfiguration;
 import org.apache.ignite.internal.processors.cache.portable.CacheObjectPortableProcessorImpl;
+import org.apache.ignite.internal.processors.platform.dotnet.PlatformDotNetConfiguration;
+import org.apache.ignite.internal.processors.platform.dotnet.PlatformDotNetPortableConfiguration;
+import org.apache.ignite.internal.processors.platform.dotnet.PlatformDotNetPortableTypeConfiguration;
 import org.apache.ignite.internal.util.GridConcurrentHashSet;
+import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.lang.GridMapEntry;
 import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.marshaller.MarshallerContext;
 import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
-import org.apache.ignite.internal.portable.api.PortableMarshaller;
-import org.apache.ignite.internal.processors.platform.dotnet.PlatformDotNetConfiguration;
-import org.apache.ignite.internal.processors.platform.dotnet.PlatformDotNetPortableConfiguration;
-import org.apache.ignite.internal.processors.platform.dotnet.PlatformDotNetPortableTypeConfiguration;
-import org.apache.ignite.internal.portable.api.PortableException;
-import org.apache.ignite.internal.portable.api.PortableIdMapper;
-import org.apache.ignite.internal.portable.api.PortableInvalidClassException;
-import org.apache.ignite.internal.portable.api.PortableMetadata;
-import org.apache.ignite.internal.portable.api.PortableSerializer;
-import org.apache.ignite.internal.portable.api.PortableTypeConfiguration;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
@@ -81,6 +82,9 @@ public class PortableContext implements Externalizable {
     private static final long serialVersionUID = 0L;
 
     /** */
+    private static final ClassLoader dfltLdr = U.gridClassLoader();
+
+    /** */
     static final PortableIdMapper DFLT_ID_MAPPER = new IdMapperWrapper(null);
 
     /** */
@@ -108,8 +112,8 @@ public class PortableContext implements Externalizable {
     /** */
     private final ConcurrentMap<Class<?>, PortableClassDescriptor> descByCls = new ConcurrentHashMap8<>();
 
-    /** */
-    private final ConcurrentMap<Integer, PortableClassDescriptor> userTypes = new ConcurrentHashMap8<>(0);
+    /** Holds classes loaded by default class loader only. */
+    private final ConcurrentMap<Integer, PortableClassDescriptor> userTypes = new ConcurrentHashMap8<>();
 
     /** */
     private final Map<Integer, PortableClassDescriptor> predefinedTypes = new HashMap<>();
@@ -124,7 +128,7 @@ public class PortableContext implements Externalizable {
     private final Map<Class<? extends Map>, Byte> mapTypes = new HashMap<>();
 
     /** */
-    private final Map<Integer, PortableIdMapper> mappers = new ConcurrentHashMap8<>(0);
+    private final ConcurrentMap<Integer, PortableIdMapper> mappers = new ConcurrentHashMap8<>(0);
 
     /** */
     private final Map<String, PortableIdMapper> typeMappers = new ConcurrentHashMap8<>(0);
@@ -454,16 +458,18 @@ public class PortableContext implements Externalizable {
     public PortableClassDescriptor descriptorForTypeId(boolean userType, int typeId, ClassLoader ldr) {
         assert typeId != GridPortableMarshaller.UNREGISTERED_TYPE_ID;
 
-        //TODO: IGNITE-1358 (uncomment when fixed)
-        //PortableClassDescriptor desc = userType ? userTypes.get(typeId) : predefinedTypes.get(typeId);
-
-        // As a workaround for IGNITE-1358 we always check the predefined map before.
+        //TODO: As a workaround for IGNITE-1358 we always check the predefined map before without checking 'userType'
         PortableClassDescriptor desc = predefinedTypes.get(typeId);
 
         if (desc != null)
             return desc;
 
-        if (userType) {
+        if (ldr == null)
+            ldr = dfltLdr;
+
+        // If the type hasn't been loaded by default class loader then we mustn't return the descriptor from here
+        // giving a chance to a custom class loader to reload type's class.
+        if (userType && ldr.equals(dfltLdr)) {
             desc = userTypes.get(typeId);
 
             if (desc != null)
@@ -478,9 +484,17 @@ public class PortableContext implements Externalizable {
             desc = descByCls.get(cls);
         }
         catch (ClassNotFoundException e) {
+            // Class might have been loaded by default class loader.
+            if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr)) != null)
+                return desc;
+
             throw new PortableInvalidClassException(e);
         }
         catch (IgniteCheckedException e) {
+            // Class might have been loaded by default class loader.
+            if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr)) != null)
+                return desc;
+
             throw new PortableException("Failed resolve class for ID: " + typeId, e);
         }
 
@@ -541,7 +555,7 @@ public class PortableContext implements Externalizable {
 
         String typeName = typeName(cls.getName());
 
-        PortableIdMapper idMapper = idMapper(typeName);
+        PortableIdMapper idMapper = userTypeIdMapper(typeName);
 
         int typeId = idMapper.typeId(typeName);
 
@@ -566,10 +580,15 @@ public class PortableContext implements Externalizable {
             false /* predefined */
         );
 
-        // perform put() instead of putIfAbsent() because "registered" flag may have been changed.
-        userTypes.put(typeId, desc);
+        // perform put() instead of putIfAbsent() because "registered" flag might have been changed or class loader
+        // might have reloaded described class.
+        if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr))
+            userTypes.put(typeId, desc);
+
         descByCls.put(cls, desc);
 
+        mappers.putIfAbsent(typeId, idMapper);
+
         // TODO uncomment for https://issues.apache.org/jira/browse/IGNITE-1377
 //        if (registerMetadata && isMetaDataEnabled(typeId))
 //            metaHnd.addMeta(typeId, new PortableMetaDataImpl(typeName, desc.fieldsMeta(), null));
@@ -619,7 +638,7 @@ public class PortableContext implements Externalizable {
         if (marshCtx.isSystemType(typeName))
             return typeName.hashCode();
 
-        return idMapper(shortTypeName).typeId(shortTypeName);
+        return userTypeIdMapper(shortTypeName).typeId(shortTypeName);
     }
 
     /**
@@ -628,20 +647,20 @@ public class PortableContext implements Externalizable {
      * @return Field ID.
      */
     public int fieldId(int typeId, String fieldName) {
-        return idMapper(typeId).fieldId(typeId, fieldName);
+        return userTypeIdMapper(typeId).fieldId(typeId, fieldName);
     }
 
     /**
      * @param typeId Type ID.
      * @return Instance of ID mapper.
      */
-    public PortableIdMapper idMapper(int typeId) {
+    public PortableIdMapper userTypeIdMapper(int typeId) {
         PortableIdMapper idMapper = mappers.get(typeId);
 
         if (idMapper != null)
             return idMapper;
 
-        if (userTypes.containsKey(typeId) || predefinedTypes.containsKey(typeId))
+        if (predefinedTypes.containsKey(typeId))
             return DFLT_ID_MAPPER;
 
         return BASIC_CLS_ID_MAPPER;
@@ -651,7 +670,7 @@ public class PortableContext implements Externalizable {
      * @param typeName Type name.
      * @return Instance of ID mapper.
      */
-    private PortableIdMapper idMapper(String typeName) {
+    private PortableIdMapper userTypeIdMapper(String typeName) {
         PortableIdMapper idMapper = typeMappers.get(typeName);
 
         return idMapper != null ? idMapper : DFLT_ID_MAPPER;
@@ -784,7 +803,9 @@ public class PortableContext implements Externalizable {
 
             fieldsMeta = desc.fieldsMeta();
 
-            userTypes.put(id, desc);
+            if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr))
+                userTypes.put(id, desc);
+
             descByCls.put(cls, desc);
         }
 
@@ -934,6 +955,22 @@ public class PortableContext implements Externalizable {
     }
 
     /**
+     * Undeployment callback invoked when class loader is being undeployed.
+     *
+     * Some marshallers may want to clean their internal state that uses the undeployed class loader somehow.
+     *
+     * @param ldr Class loader being undeployed.
+     */
+    public void onUndeploy(ClassLoader ldr) {
+        for (Class<?> cls : descByCls.keySet()) {
+            if (ldr.equals(cls.getClassLoader()))
+                descByCls.remove(cls);
+        }
+
+        U.clearClassCache(ldr);
+    }
+
+    /**
      */
     private static class IdMapperWrapper implements PortableIdMapper {
         /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java
index 3dfbdf0..24a39a7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java
@@ -349,4 +349,9 @@ public class PortableMarshaller extends AbstractMarshaller {
             throw new PortableException("Failed to unmarshal the object from InputStream", e);
         }
     }
+
+    /** {@inheritDoc} */
+    @Override public void onUndeploy(ClassLoader ldr) {
+        impl.context().onUndeploy(ldr);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
index 7d7cbec..44b91a5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
@@ -44,21 +44,27 @@ public class CacheObjectContext {
     /** */
     private boolean p2pEnabled;
 
+    /** */
+    private boolean addDepInfo;
+
     /**
      * @param kernalCtx Kernal context.
      * @param dfltAffMapper Default affinity mapper.
      * @param cpyOnGet Copy on get flag.
      * @param storeVal {@code True} if should store unmarshalled value in cache.
+     * @param addDepInfo {@code true} if deployment info should be associated with the objects of this cache.
      */
     public CacheObjectContext(GridKernalContext kernalCtx,
         AffinityKeyMapper dfltAffMapper,
         boolean cpyOnGet,
-        boolean storeVal) {
+        boolean storeVal,
+        boolean addDepInfo) {
         this.kernalCtx = kernalCtx;
         this.p2pEnabled = kernalCtx.config().isPeerClassLoadingEnabled();
         this.dfltAffMapper = dfltAffMapper;
         this.cpyOnGet = cpyOnGet;
         this.storeVal = storeVal;
+        this.addDepInfo = addDepInfo;
 
         proc = kernalCtx.cacheObjects();
     }
@@ -71,6 +77,13 @@ public class CacheObjectContext {
     }
 
     /**
+     * @return {@code True} if deployment info should be associated with the objects of this cache.
+     */
+    public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
+    /**
      * @return Copy on get flag.
      */
     public boolean copyOnGet() {
@@ -126,4 +139,4 @@ public class CacheObjectContext {
     public Collection<Object> unwrapPortablesIfNeeded(Collection<Object> col, boolean keepPortable) {
         return col;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
index 3a1cee6..1f4852c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
@@ -236,6 +236,9 @@ public class GridCacheContext<K, V> implements Externalizable {
     /** Updates allowed flag. */
     private boolean updatesAllowed;
 
+    /** Deployment enabled flag for this specific cache */
+    private boolean depEnabled;
+
     /**
      * Empty constructor required for {@link Externalizable}.
      */
@@ -312,6 +315,7 @@ public class GridCacheContext<K, V> implements Externalizable {
         this.cacheType = cacheType;
         this.affNode = affNode;
         this.updatesAllowed = updatesAllowed;
+        this.depEnabled = ctx.deploy().enabled() && !cacheObjects().isPortableEnabled(cacheCfg);
 
         /*
          * Managers in starting order!
@@ -965,7 +969,7 @@ public class GridCacheContext<K, V> implements Externalizable {
      * @return Cache transaction manager.
      */
     public IgniteTxManager tm() {
-         return sharedCtx.tm();
+        return sharedCtx.tm();
     }
 
     /**
@@ -1408,10 +1412,10 @@ public class GridCacheContext<K, V> implements Externalizable {
     }
 
     /**
-     * @return {@code True} if deployment enabled.
+     * @return {@code True} if deployment is enabled.
      */
     public boolean deploymentEnabled() {
-        return ctx.deploy().enabled();
+        return depEnabled;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionManager.java
index 1c34c76..9a89fee 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionManager.java
@@ -1742,7 +1742,8 @@ public class GridCacheEvictionManager extends GridCacheManagerAdapter {
                         // There are remote participants.
                         for (ClusterNode node : nodes) {
                             GridCacheEvictionRequest req = F.addIfAbsent(reqMap, node.id(),
-                                new GridCacheEvictionRequest(cctx.cacheId(), id, evictInfos.size(), topVer));
+                                new GridCacheEvictionRequest(cctx.cacheId(), id, evictInfos.size(), topVer,
+                                    cctx.deploymentEnabled()));
 
                             assert req != null;
 
@@ -2106,4 +2107,4 @@ public class GridCacheEvictionManager extends GridCacheManagerAdapter {
             return S.toString(EvictionFuture.class, this);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionRequest.java
index fa0359c..09652a9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionRequest.java
@@ -62,14 +62,17 @@ public class GridCacheEvictionRequest extends GridCacheMessage implements GridCa
      * @param futId Future id.
      * @param size Size.
      * @param topVer Topology version.
+     * @param addDepInfo Deployment info flag.
      */
-    GridCacheEvictionRequest(int cacheId, long futId, int size, @NotNull AffinityTopologyVersion topVer) {
+    GridCacheEvictionRequest(int cacheId, long futId, int size, @NotNull AffinityTopologyVersion topVer,
+        boolean addDepInfo) {
         assert futId > 0;
         assert size > 0;
         assert topVer.topologyVersion() > 0;
 
         this.cacheId = cacheId;
         this.futId = futId;
+        this.addDepInfo = addDepInfo;
 
         entries = new ArrayList<>(size);
 
@@ -82,15 +85,13 @@ public class GridCacheEvictionRequest extends GridCacheMessage implements GridCa
         super.prepareMarshal(ctx);
 
         if (entries != null) {
-            boolean depEnabled = ctx.deploymentEnabled();
-
             GridCacheContext cctx = ctx.cacheContext(cacheId);
 
             for (CacheEvictionEntry e : entries) {
                 e.prepareMarshal(cctx);
 
-                if (depEnabled)
-                    prepareObject(e.key().value(cctx.cacheObjectContext(), false), ctx);
+                if (addDepInfo)
+                    prepareObject(e.key().value(cctx.cacheObjectContext(), false), cctx);
             }
         }
     }
@@ -107,6 +108,11 @@ public class GridCacheEvictionRequest extends GridCacheMessage implements GridCa
         }
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
     /**
      * @return Future id.
      */
@@ -239,4 +245,4 @@ public class GridCacheEvictionRequest extends GridCacheMessage implements GridCa
     @Override public String toString() {
         return S.toString(GridCacheEvictionRequest.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionResponse.java
index aa3911b..ebaee6a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEvictionResponse.java
@@ -88,6 +88,11 @@ public class GridCacheEvictionResponse extends GridCacheMessage {
         finishUnmarshalCacheObjects(rejectedKeys, ctx.cacheContext(cacheId), ldr);
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return false;
+    }
+
     /**
      * @return Future ID.
      */
@@ -217,4 +222,4 @@ public class GridCacheEvictionResponse extends GridCacheMessage {
     @Override public String toString() {
         return S.toString(GridCacheEvictionResponse.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
index 476a96c..ec34f41 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
@@ -284,6 +284,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
 
     /**
      * Sends response on failed message.
+     *
      * @param nodeId node id.
      * @param res response.
      * @param cctx shared context.
@@ -302,6 +303,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
 
     /**
      * Processes failed messages.
+     *
      * @param nodeId niode id.
      * @param msg message.
      * @throws IgniteCheckedException If failed.
@@ -332,7 +334,8 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
                     req.version(),
                     req.futureId(),
                     req.miniId(),
-                    0);
+                    0,
+                    ctx.deploymentEnabled());
 
                 sendResponseOnFailedMessage(nodeId, res, cctx, ctx.ioPolicy());
             }
@@ -345,7 +348,8 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
                 GridDhtTxPrepareResponse res = new GridDhtTxPrepareResponse(
                     req.version(),
                     req.futureId(),
-                    req.miniId());
+                    req.miniId(),
+                    req.deployInfo() != null);
 
                 res.error(req.classError());
 
@@ -359,7 +363,8 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
 
                 GridDhtAtomicUpdateResponse res = new GridDhtAtomicUpdateResponse(
                     ctx.cacheId(),
-                    req.futureVersion());
+                    req.futureVersion(),
+                    ctx.deploymentEnabled());
 
                 res.onError(req.classError());
 
@@ -374,7 +379,8 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
                 GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(
                     ctx.cacheId(),
                     nodeId,
-                    req.futureVersion());
+                    req.futureVersion(),
+                    ctx.deploymentEnabled());
 
                 res.error(req.classError());
 
@@ -389,7 +395,8 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
                 GridDhtForceKeysResponse res = new GridDhtForceKeysResponse(
                     ctx.cacheId(),
                     req.futureId(),
-                    req.miniId()
+                    req.miniId(),
+                    ctx.deploymentEnabled()
                 );
 
                 res.error(req.classError());
@@ -414,7 +421,8 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
                     ctx.cacheId(),
                     req.futureId(),
                     req.miniId(),
-                    req.version());
+                    req.version(),
+                    req.deployInfo() != null);
 
                 res.error(req.classError());
 
@@ -456,7 +464,8 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
                     false,
                     0,
                     req.classError(),
-                    null);
+                    null,
+                    ctx.deploymentEnabled());
 
                 sendResponseOnFailedMessage(nodeId, res, cctx, ctx.ioPolicy());
             }
@@ -474,7 +483,8 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
                     req.version(),
                     null,
                     null,
-                    null);
+                    null,
+                    req.deployInfo() != null);
 
                 res.error(req.classError());
 
@@ -540,7 +550,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
         if (destNodeId == null || !cctx.localNodeId().equals(destNodeId)) {
             msg.prepareMarshal(cctx);
 
-            if (depEnabled && msg instanceof GridCacheDeployable)
+            if (msg instanceof GridCacheDeployable && msg.addDeploymentInfo())
                 cctx.deploy().prepare((GridCacheDeployable)msg);
         }
 
@@ -766,8 +776,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
     }
 
     /**
-     * @return ID that auto-grows based on local counter and counters received
-     *      from other nodes.
+     * @return ID that auto-grows based on local counter and counters received from other nodes.
      */
     public long nextIoId() {
         return idGen.incrementAndGet();
@@ -784,8 +793,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
     public void sendNoRetry(ClusterNode node,
         GridCacheMessage msg,
         byte plc)
-        throws IgniteCheckedException
-    {
+        throws IgniteCheckedException {
         assert node != null;
         assert msg != null;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java
index 4b700e0..bdd2118 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMessage.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
+import javax.cache.processor.EntryProcessor;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.GridDirectTransient;
 import org.apache.ignite.internal.managers.deployment.GridDeployment;
@@ -30,6 +31,7 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -67,6 +69,14 @@ public abstract class GridCacheMessage implements Message {
 
     /** */
     @GridDirectTransient
+    protected boolean addDepInfo;
+
+    /** Force addition of deployment info regardless of {@code addDepInfo} flag value.*/
+    @GridDirectTransient
+    protected boolean forceAddDepInfo;
+
+    /** */
+    @GridDirectTransient
     private IgniteCheckedException err;
 
     /** */
@@ -174,11 +184,20 @@ public abstract class GridCacheMessage implements Message {
     }
 
     /**
+     *  Deployment enabled flag indicates whether deployment info has to be added to this message.
+     *
+     * @return {@code true} or if deployment info must be added to the the message, {@code false} otherwise.
+     */
+    public abstract boolean addDeploymentInfo();
+
+    /**
      * @param o Object to prepare for marshalling.
      * @param ctx Context.
      * @throws IgniteCheckedException If failed.
      */
-    protected final void prepareObject(@Nullable Object o, GridCacheSharedContext ctx) throws IgniteCheckedException {
+    protected final void prepareObject(@Nullable Object o, GridCacheContext ctx) throws IgniteCheckedException {
+        assert addDepInfo || forceAddDepInfo;
+
         if (!skipPrepare && o != null) {
             GridDeploymentInfo d = ctx.deploy().globalDeploymentInfo();
 
@@ -259,16 +278,16 @@ public abstract class GridCacheMessage implements Message {
         if (info != null) {
             info.marshal(ctx);
 
-            if (ctx.deploymentEnabled()) {
+            if (addDepInfo) {
                 if (info.key() != null)
-                    prepareObject(info.key().value(ctx.cacheObjectContext(), false), ctx.shared());
+                    prepareObject(info.key().value(ctx.cacheObjectContext(), false), ctx);
 
                 CacheObject val = info.value();
 
                 if (val != null) {
                     val.finishUnmarshal(ctx.cacheObjectContext(), ctx.deploy().globalLoader());
 
-                    prepareObject(CU.value(val, ctx, false), ctx.shared());
+                    prepareObject(CU.value(val, ctx, false), ctx);
                 }
             }
         }
@@ -332,18 +351,31 @@ public abstract class GridCacheMessage implements Message {
 
         if (txEntries != null) {
             boolean transferExpiry = transferExpiryPolicy();
+            boolean p2pEnabled = ctx.deploymentEnabled();
 
             for (IgniteTxEntry e : txEntries) {
                 e.marshal(ctx, transferExpiry);
 
-                if (ctx.deploymentEnabled()) {
-                    CacheObjectContext cctx =ctx.cacheContext(e.cacheId()).cacheObjectContext();
+                GridCacheContext cctx = e.context();
 
+                if (addDepInfo) {
                     if (e.key() != null)
-                        prepareObject(e.key().value(cctx, false), ctx);
+                        prepareObject(e.key().value(cctx.cacheObjectContext(), false), cctx);
 
                     if (e.value() != null)
-                        prepareObject(e.value().value(cctx, false), ctx);
+                        prepareObject(e.value().value(cctx.cacheObjectContext(), false), cctx);
+
+                    if (e.entryProcessors() != null) {
+                        for (T2<EntryProcessor<Object, Object, Object>, Object[]> entProc : e.entryProcessors())
+                            prepareObject(entProc.get1(), cctx);
+                    }
+                }
+                else if (p2pEnabled && e.entryProcessors() != null) {
+                    if (!forceAddDepInfo)
+                        forceAddDepInfo = true;
+
+                    for (T2<EntryProcessor<Object, Object, Object>, Object[]> entProc : e.entryProcessors())
+                        prepareObject(entProc.get1(), cctx);
                 }
             }
         }
@@ -381,8 +413,8 @@ public abstract class GridCacheMessage implements Message {
      * @return Marshalled collection.
      * @throws IgniteCheckedException If failed.
      */
-    @Nullable protected final byte[][] marshalInvokeArguments(@Nullable Object[] args,
-        GridCacheSharedContext ctx) throws IgniteCheckedException {
+    @Nullable protected final byte[][] marshalInvokeArguments(@Nullable Object[] args, GridCacheContext ctx)
+        throws IgniteCheckedException {
         assert ctx != null;
 
         if (args == null || args.length == 0)
@@ -393,7 +425,7 @@ public abstract class GridCacheMessage implements Message {
         for (int i = 0; i < args.length; i++) {
             Object arg = args[i];
 
-            if (ctx.deploymentEnabled())
+            if (addDepInfo)
                 prepareObject(arg, ctx);
 
             argsBytes[i] = arg == null ? null : CU.marshal(ctx, arg);
@@ -436,7 +468,7 @@ public abstract class GridCacheMessage implements Message {
      * @throws IgniteCheckedException If failed.
      */
     @Nullable protected List<byte[]> marshalCollection(@Nullable Collection<?> col,
-        GridCacheSharedContext ctx) throws IgniteCheckedException {
+        GridCacheContext ctx) throws IgniteCheckedException {
         assert ctx != null;
 
         if (col == null)
@@ -445,7 +477,7 @@ public abstract class GridCacheMessage implements Message {
         List<byte[]> byteCol = new ArrayList<>(col.size());
 
         for (Object o : col) {
-            if (ctx.deploymentEnabled())
+            if (addDepInfo)
                 prepareObject(o, ctx);
 
             byteCol.add(o == null ? null : CU.marshal(ctx, o));
@@ -467,16 +499,14 @@ public abstract class GridCacheMessage implements Message {
 
         int size = col.size();
 
-        boolean depEnabled = ctx.deploymentEnabled();
-
         for (int i = 0 ; i < size; i++) {
             CacheObject obj = col.get(i);
 
             if (obj != null) {
                 obj.prepareMarshal(ctx.cacheObjectContext());
 
-                if (depEnabled)
-                    prepareObject(obj.value(ctx.cacheObjectContext(), false), ctx.shared());
+                if (addDepInfo)
+                    prepareObject(obj.value(ctx.cacheObjectContext(), false), ctx);
             }
         }
     }
@@ -491,14 +521,12 @@ public abstract class GridCacheMessage implements Message {
         if (col == null)
             return;
 
-        boolean depEnabled = ctx.deploymentEnabled();
-
         for (CacheObject obj : col) {
             if (obj != null) {
                 obj.prepareMarshal(ctx.cacheObjectContext());
 
-                if (depEnabled)
-                    prepareObject(obj.value(ctx.cacheObjectContext(), false), ctx.shared());
+                if (addDepInfo)
+                    prepareObject(obj.value(ctx.cacheObjectContext(), false), ctx);
             }
         }
     }
@@ -649,4 +677,4 @@ public abstract class GridCacheMessage implements Message {
     @Override public String toString() {
         return S.toString(GridCacheMessage.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
index c5d4162..b37742c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
@@ -558,6 +558,9 @@ public class GridCacheSharedContext<K, V> {
             if (store.isWriteBehind() != activeStore.isWriteBehind())
                 return "caches with different write-behind setting can't be enlisted in one transaction";
 
+            if (activeCacheCtx.deploymentEnabled() != cacheCtx.deploymentEnabled())
+                return "caches with enabled and disabled deployment modes can't be enlisted in one transaction";
+
             // If local and write-behind validations passed, this must be true.
             assert store.isWriteToStoreFromDht() == activeStore.isWriteToStoreFromDht();
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
index 7854c93..ee1f4a1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
@@ -925,11 +925,25 @@ public class GridCacheUtils {
      * @throws IgniteCheckedException If marshalling failed.
      */
     @SuppressWarnings("unchecked")
-    public static byte[] marshal(GridCacheSharedContext ctx, Object obj)
+    public static byte[] marshal(GridCacheContext ctx, Object obj)
         throws IgniteCheckedException {
         assert ctx != null;
 
-        if (ctx.gridDeploy().enabled()) {
+        return marshal(ctx.shared(), ctx.deploymentEnabled(), obj);
+    }
+
+    /**
+     * @param ctx Cache context.
+     * @param depEnabled deployment enabled flag.
+     * @param obj Object to marshal.
+     * @return Buffer that contains obtained byte array.
+     * @throws IgniteCheckedException If marshalling failed.
+     */
+    public static byte[] marshal(GridCacheSharedContext ctx, boolean depEnabled, Object obj)
+        throws IgniteCheckedException {
+        assert ctx != null;
+
+        if (depEnabled) {
             if (obj != null) {
                 if (obj instanceof Iterable)
                     ctx.deploy().registerClasses((Iterable<?>)obj);
@@ -1797,4 +1811,4 @@ public class GridCacheUtils {
             }
         };
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTtlUpdateRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTtlUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTtlUpdateRequest.java
index c911b5b..8177c98 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTtlUpdateRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTtlUpdateRequest.java
@@ -194,6 +194,11 @@ public class GridCacheTtlUpdateRequest extends GridCacheMessage {
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -327,4 +332,4 @@ public class GridCacheTtlUpdateRequest extends GridCacheMessage {
     @Override public String toString() {
         return S.toString(GridCacheTtlUpdateRequest.class, this, "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
index d6f6a18..4d75403 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
@@ -162,7 +162,8 @@ public class GridCacheTxRecoveryFuture extends GridCompoundIdentityFuture<Boolea
                     0,
                     true,
                     futureId(),
-                    fut.futureId());
+                    fut.futureId(),
+                    tx.activeCachesDeploymentEnabled());
 
                 try {
                     cctx.io().send(nearNodeId, req, tx.ioPolicy());
@@ -267,7 +268,8 @@ public class GridCacheTxRecoveryFuture extends GridCompoundIdentityFuture<Boolea
                         nodeTransactions(id),
                         false,
                         futureId(),
-                        fut.futureId());
+                        fut.futureId(),
+                        tx.activeCachesDeploymentEnabled());
 
                     try {
                         cctx.io().send(id, req, tx.ioPolicy());
@@ -292,7 +294,8 @@ public class GridCacheTxRecoveryFuture extends GridCompoundIdentityFuture<Boolea
                     nodeTransactions(nodeId),
                     false,
                     futureId(),
-                    fut.futureId());
+                    fut.futureId(),
+                    tx.activeCachesDeploymentEnabled());
 
                 try {
                     cctx.io().send(nodeId, req, tx.ioPolicy());

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryRequest.java
index bd6cd88..e5787d7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryRequest.java
@@ -64,14 +64,16 @@ public class GridCacheTxRecoveryRequest extends GridDistributedBaseMessage {
      * @param nearTxCheck {@code True} if should check only tx on near node.
      * @param futId Future ID.
      * @param miniId Mini future ID.
+     * @param addDepInfo Deployment info flag.
      */
     public GridCacheTxRecoveryRequest(IgniteInternalTx tx,
         int txNum,
         boolean nearTxCheck,
         IgniteUuid futId,
-        IgniteUuid miniId)
+        IgniteUuid miniId,
+        boolean addDepInfo)
     {
-        super(tx.xidVersion(), 0);
+        super(tx.xidVersion(), 0, addDepInfo);
 
         nearXidVer = tx.nearXidVersion();
         sys = tx.system();
@@ -258,4 +260,4 @@ public class GridCacheTxRecoveryRequest extends GridDistributedBaseMessage {
     @Override public String toString() {
         return S.toString(GridCacheTxRecoveryRequest.class, this, "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryResponse.java
index 8b9550f..361d381 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryResponse.java
@@ -53,17 +53,21 @@ public class GridCacheTxRecoveryResponse extends GridDistributedBaseMessage {
      * @param futId Future ID.
      * @param miniId Mini future ID.
      * @param success {@code True} if all remote transactions were prepared, {@code false} otherwise.
+     * @param addDepInfo Deployment info flag.
      */
     public GridCacheTxRecoveryResponse(GridCacheVersion txId,
         IgniteUuid futId,
         IgniteUuid miniId,
-        boolean success)
+        boolean success,
+        boolean addDepInfo)
     {
-        super(txId, 0);
+        super(txId, 0, addDepInfo);
 
         this.futId = futId;
         this.miniId = miniId;
         this.success = success;
+
+        this.addDepInfo = addDepInfo;
     }
 
     /**
@@ -179,4 +183,4 @@ public class GridCacheTxRecoveryResponse extends GridDistributedBaseMessage {
     @Override public String toString() {
         return S.toString(GridCacheTxRecoveryResponse.class, this, "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java
index 689cc62..f4a16dc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java
@@ -86,19 +86,22 @@ public abstract class GridDistributedBaseMessage extends GridCacheMessage implem
 
     /**
      * @param cnt Count of keys references in list of candidates.
+     * @param addDepInfo Deployment info flag.
      */
-    protected GridDistributedBaseMessage(int cnt) {
+    protected GridDistributedBaseMessage(int cnt, boolean addDepInfo) {
         assert cnt >= 0;
 
         this.cnt = cnt;
+        this.addDepInfo = addDepInfo;
     }
 
     /**
      * @param ver Either lock or transaction version.
      * @param cnt Key count.
+     * @param addDepInfo Deployment info flag.
      */
-    protected GridDistributedBaseMessage(GridCacheVersion ver, int cnt) {
-        this(cnt);
+    protected GridDistributedBaseMessage(GridCacheVersion ver, int cnt, boolean addDepInfo) {
+        this(cnt, addDepInfo);
 
         assert ver != null;
 
@@ -122,6 +125,11 @@ public abstract class GridDistributedBaseMessage extends GridCacheMessage implem
             candsByIdx = ctx.marshaller().unmarshal(candsByIdxBytes, ldr);
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
     /**
      * @return Version.
      */
@@ -290,4 +298,4 @@ public abstract class GridDistributedBaseMessage extends GridCacheMessage implem
     @Override public String toString() {
         return S.toString(GridDistributedBaseMessage.class, this, "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java
index 1963894..2899e25 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java
@@ -118,6 +118,7 @@ public class GridDistributedLockRequest extends GridDistributedBaseMessage {
      * @param keyCnt Number of keys.
      * @param txSize Expected transaction size.
      * @param skipStore Skip store flag.
+     * @param addDepInfo Deployment info flag.
      */
     public GridDistributedLockRequest(
         int cacheId,
@@ -133,9 +134,10 @@ public class GridDistributedLockRequest extends GridDistributedBaseMessage {
         long timeout,
         int keyCnt,
         int txSize,
-        boolean skipStore
+        boolean skipStore,
+        boolean addDepInfo
     ) {
-        super(lockVer, keyCnt);
+        super(lockVer, keyCnt, addDepInfo);
 
         assert keyCnt > 0;
         assert futId != null;
@@ -551,4 +553,4 @@ public class GridDistributedLockRequest extends GridDistributedBaseMessage {
         return S.toString(GridDistributedLockRequest.class, this, "keysCnt", retVals.length,
             "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java
index 8a95b14..cdd58b5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java
@@ -72,12 +72,14 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessage {
      * @param lockVer Lock version.
      * @param futId Future ID.
      * @param cnt Key count.
+     * @param addDepInfo Deployment info.
      */
     public GridDistributedLockResponse(int cacheId,
         GridCacheVersion lockVer,
         IgniteUuid futId,
-        int cnt) {
-        super(lockVer, cnt);
+        int cnt,
+        boolean addDepInfo) {
+        super(lockVer, cnt, addDepInfo);
 
         assert futId != null;
 
@@ -92,12 +94,14 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessage {
      * @param lockVer Lock ID.
      * @param futId Future ID.
      * @param err Error.
+     * @param addDepInfo Deployment info.
      */
     public GridDistributedLockResponse(int cacheId,
         GridCacheVersion lockVer,
         IgniteUuid futId,
-        Throwable err) {
-        super(lockVer, 0);
+        Throwable err,
+        boolean addDepInfo) {
+        super(lockVer, 0, addDepInfo);
 
         assert futId != null;
 
@@ -112,13 +116,15 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessage {
      * @param futId Future ID.
      * @param cnt Count.
      * @param err Error.
+     * @param addDepInfo Deployment info.
      */
     public GridDistributedLockResponse(int cacheId,
         GridCacheVersion lockVer,
         IgniteUuid futId,
         int cnt,
-        Throwable err) {
-        super(lockVer, cnt);
+        Throwable err,
+        boolean addDepInfo) {
+        super(lockVer, cnt, addDepInfo);
 
         assert futId != null;
 
@@ -325,4 +331,4 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessage {
         return S.toString(GridDistributedLockResponse.class, this,
             "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishRequest.java
index ddf6799..34b3112 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishRequest.java
@@ -89,6 +89,7 @@ public class GridDistributedTxFinishRequest extends GridDistributedBaseMessage {
      * @param committedVers Committed versions.
      * @param rolledbackVers Rolled back versions.
      * @param txSize Expected transaction size.
+     * @param addDepInfo Deployment info flag.
      */
     public GridDistributedTxFinishRequest(
         GridCacheVersion xidVer,
@@ -104,9 +105,10 @@ public class GridDistributedTxFinishRequest extends GridDistributedBaseMessage {
         GridCacheVersion baseVer,
         Collection<GridCacheVersion> committedVers,
         Collection<GridCacheVersion> rolledbackVers,
-        int txSize
+        int txSize,
+        boolean addDepInfo
     ) {
-        super(xidVer, 0);
+        super(xidVer, 0, addDepInfo);
         assert xidVer != null;
 
         this.futId = futId;

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishResponse.java
index 2cfafc1..4e17e79 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxFinishResponse.java
@@ -74,6 +74,11 @@ public class GridDistributedTxFinishResponse extends GridCacheMessage {
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -151,4 +156,4 @@ public class GridDistributedTxFinishResponse extends GridCacheMessage {
     @Override public String toString() {
         return GridToStringBuilder.toString(GridDistributedTxFinishResponse.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java
index 5ba7128..533c8ca 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java
@@ -131,15 +131,17 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
      * @param writes Write entries.
      * @param txNodes Transaction nodes mapping.
      * @param onePhaseCommit One phase commit flag.
+     * @param addDepInfo Deployment info flag.
      */
     public GridDistributedTxPrepareRequest(
         IgniteInternalTx tx,
         @Nullable Collection<IgniteTxEntry> reads,
         Collection<IgniteTxEntry> writes,
         Map<UUID, Collection<UUID>> txNodes,
-        boolean onePhaseCommit
+        boolean onePhaseCommit,
+        boolean addDepInfo
     ) {
-        super(tx.xidVersion(), 0);
+        super(tx.xidVersion(), 0, addDepInfo);
 
         writeVer = tx.writeVersion();
         threadId = tx.threadId();
@@ -337,6 +339,11 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo || forceAddDepInfo;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -605,4 +612,4 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
         return GridToStringBuilder.toString(GridDistributedTxPrepareRequest.class, this,
             "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareResponse.java
index e798458..d2c5aa4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareResponse.java
@@ -52,17 +52,19 @@ public class GridDistributedTxPrepareResponse extends GridDistributedBaseMessage
 
     /**
      * @param xid Transaction ID.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridDistributedTxPrepareResponse(GridCacheVersion xid) {
-        super(xid, 0);
+    public GridDistributedTxPrepareResponse(GridCacheVersion xid, boolean addDepInfo) {
+        super(xid, 0, addDepInfo);
     }
 
     /**
      * @param xid Lock ID.
      * @param err Error.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridDistributedTxPrepareResponse(GridCacheVersion xid, Throwable err) {
-        super(xid, 0);
+    public GridDistributedTxPrepareResponse(GridCacheVersion xid, Throwable err, boolean addDepInfo) {
+        super(xid, 0, addDepInfo);
 
         this.err = err;
     }
@@ -168,4 +170,4 @@ public class GridDistributedTxPrepareResponse extends GridDistributedBaseMessage
         return GridToStringBuilder.toString(GridDistributedTxPrepareResponse.class, this, "err",
             err == null ? "null" : err.toString(), "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
index f969737..0834e88 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
@@ -192,6 +192,11 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
         return Collections.emptyList();
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean activeCachesDeploymentEnabled() {
+        return false;
+    }
+
     /**
      * @return Checks if transaction has no entries.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedUnlockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedUnlockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedUnlockRequest.java
index 70c83f2..213a0ff 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedUnlockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedUnlockRequest.java
@@ -54,9 +54,10 @@ public class GridDistributedUnlockRequest extends GridDistributedBaseMessage {
     /**
      * @param cacheId Cache ID.
      * @param keyCnt Key count.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridDistributedUnlockRequest(int cacheId, int keyCnt) {
-        super(keyCnt);
+    public GridDistributedUnlockRequest(int cacheId, int keyCnt, boolean addDepInfo) {
+        super(keyCnt, addDepInfo);
 
         this.cacheId = cacheId;
     }
@@ -159,4 +160,4 @@ public class GridDistributedUnlockRequest extends GridDistributedBaseMessage {
     @Override public String toString() {
         return S.toString(GridDistributedUnlockRequest.class, this, "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentRequest.java
index e6a5c9a..0ef7606 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentRequest.java
@@ -52,6 +52,11 @@ public class GridDhtAffinityAssignmentRequest extends GridCacheMessage {
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean partitionExchangeMessage() {
         return true;
     }
@@ -127,4 +132,4 @@ public class GridDhtAffinityAssignmentRequest extends GridCacheMessage {
     @Override public String toString() {
         return S.toString(GridDhtAffinityAssignmentRequest.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentResponse.java
index 2798d7c..42358d9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAffinityAssignmentResponse.java
@@ -135,6 +135,11 @@ public class GridDhtAffinityAssignmentResponse extends GridCacheMessage {
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -202,4 +207,4 @@ public class GridDhtAffinityAssignmentResponse extends GridCacheMessage {
     @Override public String toString() {
         return S.toString(GridDhtAffinityAssignmentResponse.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
index 333bce2..9d02705 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
@@ -694,7 +694,8 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
                 GridNearGetResponse res = new GridNearGetResponse(ctx.cacheId(),
                     req.futureId(),
                     req.miniId(),
-                    req.version());
+                    req.version(),
+                    req.deployInfo() != null);
 
                 GridDhtFuture<Collection<GridCacheEntryInfo>> fut =
                     (GridDhtFuture<Collection<GridCacheEntryInfo>>)f;

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 2c16534..4f3e97d 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
@@ -866,7 +866,8 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
                         inTx() ? tx.subjectId() : null,
                         inTx() ? tx.taskNameHash() : 0,
                         read ? accessTtl : -1L,
-                        skipStore);
+                        skipStore,
+                        cctx.deploymentEnabled());
 
                     try {
                         for (ListIterator<GridDhtCacheEntry> it = dhtMapping.listIterator(); it.hasNext();) {
@@ -1236,4 +1237,4 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
             return S.toString(MiniFuture.class, this, "nodeId", node.id(), "super", super.toString());
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java
index 99c1b86..91ab1ca 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java
@@ -120,6 +120,7 @@ public class GridDhtLockRequest extends GridDistributedLockRequest {
      * @param taskNameHash Task name hash code.
      * @param accessTtl TTL for read operation.
      * @param skipStore Skip store flag.
+     * @param addDepInfo Deployment info flag.
      */
     public GridDhtLockRequest(
         int cacheId,
@@ -141,7 +142,8 @@ public class GridDhtLockRequest extends GridDistributedLockRequest {
         @Nullable UUID subjId,
         int taskNameHash,
         long accessTtl,
-        boolean skipStore
+        boolean skipStore,
+        boolean addDepInfo
     ) {
         super(cacheId,
             nodeId,
@@ -156,7 +158,8 @@ public class GridDhtLockRequest extends GridDistributedLockRequest {
             timeout,
             dhtCnt == 0 ? nearCnt : dhtCnt,
             txSize,
-            skipStore);
+            skipStore,
+            addDepInfo);
 
         this.topVer = topVer;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java
index f79156b..1e92b54 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockResponse.java
@@ -75,9 +75,11 @@ public class GridDhtLockResponse extends GridDistributedLockResponse {
      * @param futId Future ID.
      * @param miniId Mini future ID.
      * @param cnt Key count.
+     * @param addDepInfo Deployment info.
      */
-    public GridDhtLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, IgniteUuid miniId, int cnt) {
-        super(cacheId, lockVer, futId, cnt);
+    public GridDhtLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, IgniteUuid miniId, int cnt,
+        boolean addDepInfo) {
+        super(cacheId, lockVer, futId, cnt, addDepInfo);
 
         assert miniId != null;
 
@@ -89,9 +91,11 @@ public class GridDhtLockResponse extends GridDistributedLockResponse {
      * @param futId Future ID.
      * @param miniId Mini future ID.
      * @param err Error.
+     * @param addDepInfo
      */
-    public GridDhtLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, IgniteUuid miniId, Throwable err) {
-        super(cacheId, lockVer, futId, err);
+    public GridDhtLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, IgniteUuid miniId,
+        Throwable err, boolean addDepInfo) {
+        super(cacheId, lockVer, futId, err, addDepInfo);
 
         assert miniId != null;
 
@@ -291,4 +295,4 @@ public class GridDhtLockResponse extends GridDistributedLockResponse {
     @Override public String toString() {
         return S.toString(GridDhtLockResponse.class, this, super.toString());
     }
-}
\ No newline at end of file
+}


[30/31] ignite git commit: Ignite JMS 1.1 Streamer: Upgrade test ActiveMQ to 5.12.0.

Posted by ra...@apache.org.
Ignite JMS 1.1 Streamer: Upgrade test ActiveMQ to 5.12.0.


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

Branch: refs/heads/ignite-1790
Commit: e769c3a807b3f367fc1ef48d62ca3e055123d8ee
Parents: 9d7543a
Author: Raul Kripalani <ra...@apache.org>
Authored: Wed Oct 28 12:05:41 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Wed Oct 28 12:05:52 2015 +0000

----------------------------------------------------------------------
 modules/jms11/pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e769c3a8/modules/jms11/pom.xml
----------------------------------------------------------------------
diff --git a/modules/jms11/pom.xml b/modules/jms11/pom.xml
index 47a1495..72a643b 100644
--- a/modules/jms11/pom.xml
+++ b/modules/jms11/pom.xml
@@ -35,7 +35,7 @@
     <url>http://ignite.apache.org</url>
 
     <properties>
-        <activemq.version>5.11.1</activemq.version>
+        <activemq.version>5.12.0</activemq.version>
     </properties>
 
     <dependencies>


[17/31] ignite git commit: Exclude neighbors flag for affinity functions. This closes #80

Posted by ra...@apache.org.
Exclude neighbors flag for affinity functions. This closes #80


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

Branch: refs/heads/ignite-1790
Commit: 5a180027b174c1b76ab71a789633fe5f80bc9180
Parents: a4d625d
Author: agura <ag...@gridgain.com>
Authored: Tue Oct 27 15:57:59 2015 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Tue Oct 27 16:01:23 2015 +0300

----------------------------------------------------------------------
 .../ClientAbstractMultiThreadedSelfTest.java    |   3 +-
 .../affinity/fair/FairAffinityFunction.java     | 497 ++++++++++++++-----
 .../rendezvous/RendezvousAffinityFunction.java  | 140 ++----
 .../processors/cache/GridCacheProcessor.java    |  13 -
 .../processors/cache/GridCacheUtils.java        |  50 ++
 .../AbstractAffinityFunctionSelfTest.java       | 293 +++++++++++
 .../affinity/AffinityClientNodeSelfTest.java    | 194 ++++++++
 ...ityFunctionBackupFilterAbstractSelfTest.java | 138 +++++
 ...unctionExcludeNeighborsAbstractSelfTest.java | 182 +++++++
 .../affinity/IgniteClientNodeAffinityTest.java  | 194 --------
 .../fair/FairAffinityDynamicCacheSelfTest.java  |  97 ++++
 ...airAffinityFunctionBackupFilterSelfTest.java |  35 ++
 ...ffinityFunctionExcludeNeighborsSelfTest.java |  31 ++
 .../fair/FairAffinityFunctionNodesSelfTest.java | 245 +++++++++
 .../fair/FairAffinityFunctionSelfTest.java      |  31 ++
 .../GridFairAffinityFunctionNodesSelfTest.java  | 245 ---------
 .../fair/GridFairAffinityFunctionSelfTest.java  | 270 ----------
 .../IgniteFairAffinityDynamicCacheSelfTest.java |  97 ----
 ...ousAffinityFunctionBackupFilterSelfTest.java |  35 ++
 ...ffinityFunctionExcludeNeighborsSelfTest.java |  32 ++
 .../RendezvousAffinityFunctionSelfTest.java     |  50 ++
 .../cache/CrossCacheTxRandomOperationsTest.java |   2 +-
 .../GridCacheAbstractLocalStoreSelfTest.java    |   5 +
 ...idCacheConfigurationConsistencySelfTest.java |  17 -
 ...dCachePartitionedAffinityFilterSelfTest.java | 143 ------
 .../dht/GridCacheDhtPreloadPutGetSelfTest.java  |   3 +
 ...unctionExcludeNeighborsAbstractSelfTest.java | 184 -------
 ...ffinityFunctionExcludeNeighborsSelfTest.java |  32 --
 ...xcludeNeighborsMultiNodeFullApiSelfTest.java |  36 ++
 ...tedFairAffinityMultiNodeFullApiSelfTest.java |  35 ++
 ...xcludeNeighborsMultiNodeFullApiSelfTest.java |  36 ++
 ...dezvousAffinityMultiNodeFullApiSelfTest.java |  36 ++
 .../IgniteCacheFullApiSelfTestSuite.java        |   8 +
 .../ignite/testsuites/IgniteCacheTestSuite.java |  16 +-
 .../testsuites/IgniteCacheTestSuite2.java       |  12 +-
 .../cache/IgniteCacheAbstractQuerySelfTest.java |   4 +
 36 files changed, 2021 insertions(+), 1420 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientAbstractMultiThreadedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientAbstractMultiThreadedSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientAbstractMultiThreadedSelfTest.java
index 9dd4d83..9f6bf2b 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientAbstractMultiThreadedSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientAbstractMultiThreadedSelfTest.java
@@ -254,8 +254,7 @@ public abstract class ClientAbstractMultiThreadedSelfTest extends GridCommonAbst
         final ConcurrentLinkedQueue<String> execQueue = new ConcurrentLinkedQueue<>();
 
         IgniteInternalFuture<?> fut = multithreadedAsync(new Runnable() {
-            @Override
-            public void run() {
+            @Override public void run() {
                 long processed;
 
                 while ((processed = cnt.getAndIncrement()) < taskExecutionCount()) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/main/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunction.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunction.java b/modules/core/src/main/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunction.java
index cc04875..b42b683 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunction.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunction.java
@@ -31,6 +31,7 @@ import java.util.Map;
 import java.util.Queue;
 import java.util.RandomAccess;
 import java.util.UUID;
+import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cache.affinity.AffinityCentralizedFunction;
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cache.affinity.AffinityFunctionContext;
@@ -38,15 +39,38 @@ import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.events.EventType;
+import org.apache.ignite.internal.processors.cache.GridCacheUtils;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.internal.util.typedef.internal.LT;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteBiPredicate;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.resources.LoggerResource;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Fair affinity function which tries to ensure that all nodes get equal number of partitions with
  * minimum amount of reassignments between existing nodes.
+ * This function supports the following configuration:
+ * <ul>
+ * <li>
+ *      {@code partitions} - Number of partitions to spread across nodes.
+ * </li>
+ * <li>
+ *      {@code excludeNeighbors} - If set to {@code true}, will exclude same-host-neighbors
+ *      from being backups of each other. This flag can be ignored in cases when topology has no enough nodes
+ *      for assign backups.
+ *      Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
+ * </li>
+ * <li>
+ *      {@code backupFilter} - Optional filter for back up nodes. If provided, then only
+ *      nodes that pass this filter will be selected as backup nodes. If not provided, then
+ *      primary and backup nodes will be selected out of all nodes available for this cache.
+ * </li>
+ * </ul>
  * <p>
- * Cache affinity can be configured for individual caches via
- * {@link CacheConfiguration#setAffinity(AffinityFunction)} method.
+ * Cache affinity can be configured for individual caches via {@link CacheConfiguration#getAffinity()} method.
  */
 @AffinityCentralizedFunction
 public class FairAffinityFunction implements AffinityFunction {
@@ -62,21 +86,165 @@ public class FairAffinityFunction implements AffinityFunction {
     /** Descending comparator. */
     private static final Comparator<PartitionSet> DESC_CMP = Collections.reverseOrder(ASC_CMP);
 
-    /** */
-    private final int parts;
+    /** Number of partitions. */
+    private int parts;
+
+    /** Exclude neighbors flag. */
+    private boolean exclNeighbors;
+
+    /** Exclude neighbors warning. */
+    private transient boolean exclNeighborsWarn;
+
+    /** Logger instance. */
+    @LoggerResource
+    private transient IgniteLogger log;
+
+    /** Optional backup filter. First node is primary, second node is a node being tested. */
+    private IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter;
 
     /**
-     * Creates fair affinity with default partition count.
+     * Empty constructor with all defaults.
      */
     public FairAffinityFunction() {
-        this(DFLT_PART_CNT);
+        this(false);
+    }
+
+    /**
+     * Initializes affinity with flag to exclude same-host-neighbors from being backups of each other
+     * and specified number of backups.
+     * <p>
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
+     *
+     * @param exclNeighbors {@code True} if nodes residing on the same host may not act as backups
+     *      of each other.
+     */
+    public FairAffinityFunction(boolean exclNeighbors) {
+        this(exclNeighbors, DFLT_PART_CNT);
     }
 
     /**
      * @param parts Number of partitions.
      */
     public FairAffinityFunction(int parts) {
+        this(false, parts);
+    }
+
+    /**
+     * Initializes affinity with flag to exclude same-host-neighbors from being backups of each other,
+     * and specified number of backups and partitions.
+     * <p>
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
+     *
+     * @param exclNeighbors {@code True} if nodes residing on the same host may not act as backups
+     *      of each other.
+     * @param parts Total number of partitions.
+     */
+    public FairAffinityFunction(boolean exclNeighbors, int parts) {
+        this(exclNeighbors, parts, null);
+    }
+
+    /**
+     * Initializes optional counts for replicas and backups.
+     * <p>
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
+     *
+     * @param parts Total number of partitions.
+     * @param backupFilter Optional back up filter for nodes. If provided, backups will be selected
+     *      from all nodes that pass this filter. First argument for this filter is primary node, and second
+     *      argument is node being tested.
+     */
+    public FairAffinityFunction(int parts, @Nullable IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter) {
+        this(false, parts, backupFilter);
+    }
+
+    /**
+     * Private constructor.
+     *
+     * @param exclNeighbors Exclude neighbors flag.
+     * @param parts Partitions count.
+     * @param backupFilter Backup filter.
+     */
+    private FairAffinityFunction(boolean exclNeighbors, int parts,
+        IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter) {
+        A.ensure(parts > 0, "parts > 0");
+
+        this.exclNeighbors = exclNeighbors;
         this.parts = parts;
+        this.backupFilter = backupFilter;
+    }
+
+    /**
+     * Gets total number of key partitions. To ensure that all partitions are
+     * equally distributed across all nodes, please make sure that this
+     * number is significantly larger than a number of nodes. Also, partition
+     * size should be relatively small. Try to avoid having partitions with more
+     * than quarter million keys.
+     * <p>
+     * Note that for fully replicated caches this method should always
+     * return {@code 1}.
+     *
+     * @return Total partition count.
+     */
+    public int getPartitions() {
+        return parts;
+    }
+
+    /**
+     * Sets total number of partitions.
+     *
+     * @param parts Total number of partitions.
+     */
+    public void setPartitions(int parts) {
+        this.parts = parts;
+    }
+
+
+    /**
+     * Gets optional backup filter. If not {@code null}, backups will be selected
+     * from all nodes that pass this filter. First node passed to this filter is primary node,
+     * and second node is a node being tested.
+     * <p>
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
+     *
+     * @return Optional backup filter.
+     */
+    @Nullable public IgniteBiPredicate<ClusterNode, ClusterNode> getBackupFilter() {
+        return backupFilter;
+    }
+
+    /**
+     * Sets optional backup filter. If provided, then backups will be selected from all
+     * nodes that pass this filter. First node being passed to this filter is primary node,
+     * and second node is a node being tested.
+     * <p>
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
+     *
+     * @param backupFilter Optional backup filter.
+     */
+    public void setBackupFilter(@Nullable IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter) {
+        this.backupFilter = backupFilter;
+    }
+
+    /**
+     * Checks flag to exclude same-host-neighbors from being backups of each other (default is {@code false}).
+     * <p>
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
+     *
+     * @return {@code True} if nodes residing on the same host may not act as backups of each other.
+     */
+    public boolean isExcludeNeighbors() {
+        return exclNeighbors;
+    }
+
+    /**
+     * Sets flag to exclude same-host-neighbors from being backups of each other (default is {@code false}).
+     * <p>
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
+     *
+     * @param exclNeighbors {@code True} if nodes residing on the same host may not act as backups of each other.
+     */
+    public void setExcludeNeighbors(boolean exclNeighbors) {
+        this.exclNeighbors = exclNeighbors;
     }
 
     /** {@inheritDoc} */
@@ -89,14 +257,20 @@ public class FairAffinityFunction implements AffinityFunction {
             return Collections.nCopies(parts, Collections.singletonList(primary));
         }
 
-        List<List<ClusterNode>> assignment = createCopy(ctx);
+        Map<UUID, Collection<ClusterNode>> neighborhoodMap = exclNeighbors
+            ? GridCacheUtils.neighbors(ctx.currentTopologySnapshot())
+            : null;
+
+        List<List<ClusterNode>> assignment = createCopy(ctx, neighborhoodMap);
+
+        int backups = ctx.backups();
 
-        int tiers = Math.min(ctx.backups() + 1, topSnapshot.size());
+        int tiers = backups == Integer.MAX_VALUE ? topSnapshot.size() : Math.min(backups + 1, topSnapshot.size());
 
         // Per tier pending partitions.
         Map<Integer, Queue<Integer>> pendingParts = new HashMap<>();
 
-        FullAssignmentMap fullMap = new FullAssignmentMap(tiers, assignment, topSnapshot);
+        FullAssignmentMap fullMap = new FullAssignmentMap(tiers, assignment, topSnapshot, neighborhoodMap);
 
         for (int tier = 0; tier < tiers; tier++) {
             // Check if this is a new tier and add pending partitions.
@@ -104,23 +278,32 @@ public class FairAffinityFunction implements AffinityFunction {
 
             for (int part = 0; part < parts; part++) {
                 if (fullMap.assignments.get(part).size() < tier + 1) {
-                    if (pending == null) {
-                        pending = new LinkedList<>();
-
-                        pendingParts.put(tier, pending);
-                    }
+                    if (pending == null)
+                        pendingParts.put(tier, pending = new LinkedList<>());
 
                     if (!pending.contains(part))
                         pending.add(part);
-
                 }
             }
 
             // Assign pending partitions, if any.
-            assignPending(tier, pendingParts, fullMap, topSnapshot);
+            assignPending(tier, pendingParts, fullMap, topSnapshot, false);
 
             // Balance assignments.
-            balance(tier, pendingParts, fullMap, topSnapshot);
+            boolean balanced = balance(tier, pendingParts, fullMap, topSnapshot, false);
+
+            if (!balanced && exclNeighbors) {
+                assignPending(tier, pendingParts, fullMap, topSnapshot, true);
+
+                balance(tier, pendingParts, fullMap, topSnapshot, true);
+
+                if (!exclNeighborsWarn) {
+                    LT.warn(log, null, "Affinity function excludeNeighbors property is ignored " +
+                        "because topology has no enough nodes to assign backups.");
+
+                    exclNeighborsWarn = true;
+                }
+            }
         }
 
         return fullMap.assignments;
@@ -153,9 +336,14 @@ public class FairAffinityFunction implements AffinityFunction {
      * @param pendingMap Pending partitions per tier.
      * @param fullMap Full assignment map to modify.
      * @param topSnapshot Topology snapshot.
+     * @param allowNeighbors Allow neighbors nodes for partition.
      */
-    private void assignPending(int tier, Map<Integer, Queue<Integer>> pendingMap, FullAssignmentMap fullMap,
-        List<ClusterNode> topSnapshot) {
+    private void assignPending(int tier,
+        Map<Integer, Queue<Integer>> pendingMap,
+        FullAssignmentMap fullMap,
+        List<ClusterNode> topSnapshot,
+        boolean allowNeighbors)
+    {
         Queue<Integer> pending = pendingMap.get(tier);
 
         if (F.isEmpty(pending))
@@ -168,19 +356,18 @@ public class FairAffinityFunction implements AffinityFunction {
         PrioritizedPartitionMap underloadedNodes = filterNodes(tierMapping, idealPartCnt, false);
 
         // First iterate over underloaded nodes.
-        assignPendingToUnderloaded(tier, pendingMap, fullMap, underloadedNodes, topSnapshot, false);
+        assignPendingToUnderloaded(tier, pendingMap, fullMap, underloadedNodes, topSnapshot, false, allowNeighbors);
 
         if (!pending.isEmpty() && !underloadedNodes.isEmpty()) {
             // Same, forcing updates.
-            assignPendingToUnderloaded(tier, pendingMap, fullMap, underloadedNodes, topSnapshot, true);
+            assignPendingToUnderloaded(tier, pendingMap, fullMap, underloadedNodes, topSnapshot, true, allowNeighbors);
         }
 
         if (!pending.isEmpty())
-            assignPendingToNodes(tier, pendingMap, fullMap, topSnapshot);
-
-        assert pending.isEmpty();
+            assignPendingToNodes(tier, pendingMap, fullMap, topSnapshot, allowNeighbors);
 
-        pendingMap.remove(tier);
+        if (pending.isEmpty())
+            pendingMap.remove(tier);
     }
 
     /**
@@ -192,6 +379,7 @@ public class FairAffinityFunction implements AffinityFunction {
      * @param underloadedNodes Underloaded nodes.
      * @param topSnapshot Topology snapshot.
      * @param force {@code True} if partitions should be moved.
+     * @param allowNeighbors Allow neighbors nodes for partition.
      */
     private void assignPendingToUnderloaded(
         int tier,
@@ -199,7 +387,8 @@ public class FairAffinityFunction implements AffinityFunction {
         FullAssignmentMap fullMap,
         PrioritizedPartitionMap underloadedNodes,
         Collection<ClusterNode> topSnapshot,
-        boolean force) {
+        boolean force,
+        boolean allowNeighbors) {
         Iterator<Integer> it = pendingMap.get(tier).iterator();
 
         int ideal = parts / topSnapshot.size();
@@ -212,7 +401,7 @@ public class FairAffinityFunction implements AffinityFunction {
 
                 assert node != null;
 
-                if (fullMap.assign(part, tier, node, force, pendingMap)) {
+                if (fullMap.assign(part, tier, node, pendingMap, force, allowNeighbors)) {
                     // We could add partition to partition map without forcing, remove partition from pending.
                     it.remove();
 
@@ -237,9 +426,10 @@ public class FairAffinityFunction implements AffinityFunction {
      * @param pendingMap Pending partitions per tier.
      * @param fullMap Full assignment map to modify.
      * @param topSnapshot Topology snapshot.
+     * @param allowNeighbors Allow neighbors nodes for partition.
      */
     private void assignPendingToNodes(int tier, Map<Integer, Queue<Integer>> pendingMap,
-        FullAssignmentMap fullMap, List<ClusterNode> topSnapshot) {
+        FullAssignmentMap fullMap, List<ClusterNode> topSnapshot, boolean allowNeighbors) {
         Iterator<Integer> it = pendingMap.get(tier).iterator();
 
         int idx = 0;
@@ -254,7 +444,7 @@ public class FairAffinityFunction implements AffinityFunction {
             do {
                 ClusterNode node = topSnapshot.get(i);
 
-                if (fullMap.assign(part, tier, node, false, pendingMap)) {
+                if (fullMap.assign(part, tier, node, pendingMap, false, allowNeighbors)) {
                     it.remove();
 
                     assigned = true;
@@ -270,7 +460,7 @@ public class FairAffinityFunction implements AffinityFunction {
                 do {
                     ClusterNode node = topSnapshot.get(i);
 
-                    if (fullMap.assign(part, tier, node, true, pendingMap)) {
+                    if (fullMap.assign(part, tier, node, pendingMap, true, allowNeighbors)) {
                         it.remove();
 
                         assigned = true;
@@ -283,7 +473,7 @@ public class FairAffinityFunction implements AffinityFunction {
                 } while (i != idx);
             }
 
-            if (!assigned)
+            if (!assigned && (!exclNeighbors || exclNeighbors && allowNeighbors))
                 throw new IllegalStateException("Failed to find assignable node for partition.");
         }
     }
@@ -295,9 +485,10 @@ public class FairAffinityFunction implements AffinityFunction {
      * @param pendingParts Pending partitions per tier.
      * @param fullMap Full assignment map to modify.
      * @param topSnapshot Topology snapshot.
+     * @param allowNeighbors Allow neighbors nodes for partition.
      */
-    private void balance(int tier, Map<Integer, Queue<Integer>> pendingParts, FullAssignmentMap fullMap,
-        Collection<ClusterNode> topSnapshot) {
+    private boolean balance(int tier, Map<Integer, Queue<Integer>> pendingParts, FullAssignmentMap fullMap,
+        Collection<ClusterNode> topSnapshot, boolean allowNeighbors) {
         int idealPartCnt = parts / topSnapshot.size();
 
         Map<UUID, PartitionSet> mapping = fullMap.tierMapping(tier);
@@ -313,7 +504,7 @@ public class FairAffinityFunction implements AffinityFunction {
                     boolean assigned = false;
 
                     for (PartitionSet underloaded : underloadedNodes.assignments()) {
-                        if (fullMap.assign(part, tier, underloaded.node(), false, pendingParts)) {
+                        if (fullMap.assign(part, tier, underloaded.node(), pendingParts, false, allowNeighbors)) {
                             // Size of partition sets has changed.
                             if (overloaded.size() <= idealPartCnt)
                                 overloadedNodes.remove(overloaded.nodeId());
@@ -335,7 +526,7 @@ public class FairAffinityFunction implements AffinityFunction {
 
                     if (!assigned) {
                         for (PartitionSet underloaded : underloadedNodes.assignments()) {
-                            if (fullMap.assign(part, tier, underloaded.node(), true, pendingParts)) {
+                            if (fullMap.assign(part, tier, underloaded.node(), pendingParts, true, allowNeighbors)) {
                                 // Size of partition sets has changed.
                                 if (overloaded.size() <= idealPartCnt)
                                     overloadedNodes.remove(overloaded.nodeId());
@@ -366,6 +557,8 @@ public class FairAffinityFunction implements AffinityFunction {
                 break;
         }
         while (true);
+
+        return underloadedNodes.isEmpty();
     }
 
     /**
@@ -393,9 +586,12 @@ public class FairAffinityFunction implements AffinityFunction {
      * Creates copy of previous partition assignment.
      *
      * @param ctx Affinity function context.
+     * @param neighborhoodMap Neighbors nodes grouped by target node.
      * @return Assignment copy and per node partition map.
      */
-    private List<List<ClusterNode>> createCopy(AffinityFunctionContext ctx) {
+    private List<List<ClusterNode>> createCopy(AffinityFunctionContext ctx,
+        Map<UUID, Collection<ClusterNode>> neighborhoodMap)
+    {
         DiscoveryEvent discoEvt = ctx.discoveryEvent();
 
         UUID leftNodeId = (discoEvt == null || discoEvt.type() == EventType.EVT_NODE_JOINED)
@@ -411,26 +607,42 @@ public class FairAffinityFunction implements AffinityFunction {
 
             if (partNodes == null)
                 partNodesCp = new ArrayList<>();
-            else {
-                if (leftNodeId == null) {
-                    partNodesCp = new ArrayList<>(partNodes.size() + 1); // Node joined.
+            else
+                partNodesCp = copyAssigments(neighborhoodMap, partNodes, leftNodeId);
 
-                    partNodesCp.addAll(partNodes);
-                }
-                else {
-                    partNodesCp = new ArrayList<>(partNodes.size());
+            cp.add(partNodesCp);
+        }
+
+        return cp;
+    }
+
+    /**
+     * @param neighborhoodMap Neighbors nodes grouped by target node.
+     * @param partNodes Partition nodes.
+     * @param leftNodeId Left node id.
+     */
+    private List<ClusterNode> copyAssigments(Map<UUID, Collection<ClusterNode>> neighborhoodMap,
+        List<ClusterNode> partNodes, UUID leftNodeId) {
+        final List<ClusterNode> partNodesCp = new ArrayList<>(partNodes.size());
+
+        for (ClusterNode node : partNodes) {
+            if (node.id().equals(leftNodeId))
+                continue;
+
+            boolean containsNeighbor = false;
 
-                    for (ClusterNode affNode : partNodes) {
-                        if (!affNode.id().equals(leftNodeId))
-                            partNodesCp.add(affNode);
+            if (neighborhoodMap != null)
+                containsNeighbor = F.exist(neighborhoodMap.get(node.id()), new IgnitePredicate<ClusterNode>() {
+                    @Override public boolean apply(ClusterNode node) {
+                        return partNodesCp.contains(node);
                     }
-                }
-            }
+                });
 
-            cp.add(partNodesCp);
+            if (!containsNeighbor)
+                partNodesCp.add(node);
         }
 
-        return cp;
+        return partNodesCp;
     }
 
     /**
@@ -512,59 +724,11 @@ public class FairAffinityFunction implements AffinityFunction {
     }
 
     /**
-     * Constructs assignment map for specified tier.
-     *
-     * @param tier Tier number, -1 for all tiers altogether.
-     * @param assignment Assignment to construct map from.
-     * @param topSnapshot Topology snapshot.
-     * @return Assignment map.
-     */
-    private static Map<UUID, PartitionSet> assignments(int tier, List<List<ClusterNode>> assignment,
-        Collection<ClusterNode> topSnapshot) {
-        Map<UUID, PartitionSet> tmp = new LinkedHashMap<>();
-
-        for (int part = 0; part < assignment.size(); part++) {
-            List<ClusterNode> nodes = assignment.get(part);
-
-            assert nodes instanceof RandomAccess;
-
-            if (nodes.size() <= tier)
-                continue;
-
-            int start = tier < 0 ? 0 : tier;
-            int end = tier < 0 ? nodes.size() : tier + 1;
-
-            for (int i = start; i < end; i++) {
-                ClusterNode n = nodes.get(i);
-
-                PartitionSet set = tmp.get(n.id());
-
-                if (set == null) {
-                    set = new PartitionSet(n);
-
-                    tmp.put(n.id(), set);
-                }
-
-                set.add(part);
-            }
-        }
-
-        if (tmp.size() < topSnapshot.size()) {
-            for (ClusterNode node : topSnapshot) {
-                if (!tmp.containsKey(node.id()))
-                    tmp.put(node.id(), new PartitionSet(node));
-            }
-        }
-
-        return tmp;
-    }
-
-    /**
      * Full assignment map. Auxiliary data structure which maintains resulting assignment and temporary
      * maps consistent.
      */
     @SuppressWarnings("unchecked")
-    private static class FullAssignmentMap {
+    private class FullAssignmentMap {
         /** Per-tier assignment maps. */
         private Map<UUID, PartitionSet>[] tierMaps;
 
@@ -574,20 +738,28 @@ public class FairAffinityFunction implements AffinityFunction {
         /** Resulting assignment. */
         private List<List<ClusterNode>> assignments;
 
+        /** Neighborhood map. */
+        private final Map<UUID, Collection<ClusterNode>> neighborhoodMap;
+
         /**
          * @param tiers Number of tiers.
          * @param assignments Assignments to modify.
          * @param topSnapshot Topology snapshot.
+         * @param neighborhoodMap Neighbors nodes grouped by target node.
          */
-        private FullAssignmentMap(int tiers, List<List<ClusterNode>> assignments, Collection<ClusterNode> topSnapshot) {
+        private FullAssignmentMap(int tiers,
+            List<List<ClusterNode>> assignments,
+            Collection<ClusterNode> topSnapshot,
+            Map<UUID, Collection<ClusterNode>> neighborhoodMap)
+        {
             this.assignments = assignments;
-
-            tierMaps = new Map[tiers];
+            this.neighborhoodMap = neighborhoodMap;
+            this.tierMaps = new Map[tiers];
 
             for (int tier = 0; tier < tiers; tier++)
-                tierMaps[tier] = assignments(tier, assignments, topSnapshot);
+                tierMaps[tier] = assignments(tier, topSnapshot);
 
-            fullMap = assignments(-1, assignments, topSnapshot);
+            fullMap = assignments(-1, topSnapshot);
         }
 
         /**
@@ -599,14 +771,20 @@ public class FairAffinityFunction implements AffinityFunction {
          * @param part Partition to assign.
          * @param tier Tier number to assign.
          * @param node Node to move partition to.
-         * @param force Force flag.
          * @param pendingParts per tier pending partitions map.
+         * @param force Force flag.
+         * @param allowNeighbors Allow neighbors nodes for partition.
          * @return {@code True} if assignment succeeded.
          */
-        boolean assign(int part, int tier, ClusterNode node, boolean force, Map<Integer, Queue<Integer>> pendingParts) {
+        boolean assign(int part,
+            int tier,
+            ClusterNode node,
+            Map<Integer, Queue<Integer>> pendingParts, boolean force,
+            boolean allowNeighbors)
+        {
             UUID nodeId = node.id();
 
-            if (!fullMap.get(nodeId).contains(part)) {
+            if (isAssignable(part, tier, node, allowNeighbors)) {
                 tierMaps[tier].get(nodeId).add(part);
 
                 fullMap.get(nodeId).add(part);
@@ -656,11 +834,8 @@ public class FairAffinityFunction implements AffinityFunction {
 
                         Queue<Integer> pending = pendingParts.get(t);
 
-                        if (pending == null) {
-                            pending = new LinkedList<>();
-
-                            pendingParts.put(t, pending);
-                        }
+                        if (pending == null)
+                            pendingParts.put(t, pending = new LinkedList<>());
 
                         pending.add(part);
 
@@ -668,7 +843,7 @@ public class FairAffinityFunction implements AffinityFunction {
                     }
                 }
 
-                throw new IllegalStateException("Unable to assign partition to node while force is true.");
+                return false;
             }
 
             // !force.
@@ -684,6 +859,102 @@ public class FairAffinityFunction implements AffinityFunction {
         public Map<UUID, PartitionSet> tierMapping(int tier) {
             return tierMaps[tier];
         }
+
+        /**
+         * @param part Partition.
+         * @param tier Tier.
+         * @param node Node.
+         * @param allowNeighbors Allow neighbors.
+         */
+        private boolean isAssignable(int part, int tier, final ClusterNode node, boolean allowNeighbors) {
+            if (containsPartition(part, node))
+                return false;
+
+            if (exclNeighbors)
+                return allowNeighbors || !neighborsContainPartition(node, part);
+            else if (backupFilter == null)
+                return true;
+            else {
+                if (tier == 0) {
+                    List<ClusterNode> assigment = assignments.get(part);
+
+                    assert assigment.size() > 0;
+
+                    List<ClusterNode> backups = assigment.subList(1, assigment.size());
+
+                    return !F.exist(backups, new IgnitePredicate<ClusterNode>() {
+                        @Override public boolean apply(ClusterNode n) {
+                            return !backupFilter.apply(node, n);
+                        }
+                    });
+                }
+                else
+                    return (backupFilter.apply(assignments.get(part).get(0), node));
+            }
+        }
+
+        /**
+         * @param part Partition.
+         * @param node Node.
+         */
+        private boolean containsPartition(int part, ClusterNode node) {
+            return fullMap.get(node.id()).contains(part);
+        }
+
+        /**
+         * @param node Node.
+         * @param part Partition.
+         */
+        private boolean neighborsContainPartition(ClusterNode node, final int part) {
+            return F.exist(neighborhoodMap.get(node.id()), new IgnitePredicate<ClusterNode>() {
+                @Override public boolean apply(ClusterNode n) {
+                    return fullMap.get(n.id()).contains(part);
+                }
+            });
+        }
+
+        /**
+         * Constructs assignments map for specified tier.
+         *
+         * @param tier Tier number, -1 for all tiers altogether.
+         * @param topSnapshot Topology snapshot.
+         * @return Assignment map.
+         */
+        private Map<UUID, PartitionSet> assignments(int tier, Collection<ClusterNode> topSnapshot) {
+            Map<UUID, PartitionSet> tmp = new LinkedHashMap<>();
+
+            for (int part = 0; part < assignments.size(); part++) {
+                List<ClusterNode> nodes = assignments.get(part);
+
+                assert nodes instanceof RandomAccess;
+
+                if (nodes.size() <= tier)
+                    continue;
+
+                int start = tier < 0 ? 0 : tier;
+                int end = tier < 0 ? nodes.size() : tier + 1;
+
+                for (int i = start; i < end; i++) {
+                    ClusterNode n = nodes.get(i);
+
+                    PartitionSet set = tmp.get(n.id());
+
+                    if (set == null)
+                        tmp.put(n.id(), set = new PartitionSet(n));
+
+                    set.add(part);
+                }
+            }
+
+            if (tmp.size() < topSnapshot.size()) {
+                for (ClusterNode node : topSnapshot) {
+                    if (!tmp.containsKey(node.id()))
+                        tmp.put(node.id(), new PartitionSet(node));
+                }
+            }
+
+            return tmp;
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
index fd07eb9..61a21d3 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
@@ -29,26 +29,28 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cache.affinity.AffinityFunctionContext;
 import org.apache.ignite.cache.affinity.AffinityNodeHashResolver;
 import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteNodeAttributes;
+import org.apache.ignite.internal.processors.cache.GridCacheUtils;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.internal.util.typedef.internal.LT;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiPredicate;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.resources.IgniteInstanceResource;
+import org.apache.ignite.resources.LoggerResource;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -60,8 +62,9 @@ import org.jetbrains.annotations.Nullable;
  * </li>
  * <li>
  *      {@code excludeNeighbors} - If set to {@code true}, will exclude same-host-neighbors
- *      from being backups of each other. Note that {@code backupFilter} is ignored if
- *      {@code excludeNeighbors} is set to {@code true}.
+ *      from being backups of each other. This flag can be ignored in cases when topology has no enough nodes
+ *      for assign backups.
+ *      Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
  * </li>
  * <li>
  *      {@code backupFilter} - Optional filter for back up nodes. If provided, then only
@@ -70,7 +73,7 @@ import org.jetbrains.annotations.Nullable;
  * </li>
  * </ul>
  * <p>
- * Cache affinity can be configured for individual caches via {@link org.apache.ignite.configuration.CacheConfiguration#getAffinity()} method.
+ * Cache affinity can be configured for individual caches via {@link CacheConfiguration#getAffinity()} method.
  */
 public class RendezvousAffinityFunction implements AffinityFunction, Externalizable {
     /** */
@@ -80,8 +83,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     public static final int DFLT_PARTITION_COUNT = 1024;
 
     /** Comparator. */
-    private static final Comparator<IgniteBiTuple<Long, ClusterNode>> COMPARATOR =
-        new HashComparator();
+    private static final Comparator<IgniteBiTuple<Long, ClusterNode>> COMPARATOR = new HashComparator();
 
     /** Thread local message digest. */
     private ThreadLocal<MessageDigest> digest = new ThreadLocal<MessageDigest>() {
@@ -92,8 +94,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
             catch (NoSuchAlgorithmException e) {
                 assert false : "Should have failed in constructor";
 
-                throw new IgniteException("Failed to obtain message digest (digest was available in constructor)",
-                    e);
+                throw new IgniteException("Failed to obtain message digest (digest was available in constructor)", e);
             }
         }
     };
@@ -104,6 +105,9 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     /** Exclude neighbors flag. */
     private boolean exclNeighbors;
 
+    /** Exclude neighbors warning. */
+    private transient boolean exclNeighborsWarn;
+
     /** Optional backup filter. First node is primary, second node is a node being tested. */
     private IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter;
 
@@ -114,6 +118,10 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     @IgniteInstanceResource
     private Ignite ignite;
 
+    /** Logger instance. */
+    @LoggerResource
+    private transient IgniteLogger log;
+
     /**
      * Empty constructor with all defaults.
      */
@@ -125,7 +133,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
      * Initializes affinity with flag to exclude same-host-neighbors from being backups of each other
      * and specified number of backups.
      * <p>
-     * Note that {@code excludeNeighbors} parameter is ignored if {@code #getBackupFilter()} is set.
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
      *
      * @param exclNeighbors {@code True} if nodes residing on the same host may not act as backups
      *      of each other.
@@ -138,7 +146,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
      * Initializes affinity with flag to exclude same-host-neighbors from being backups of each other,
      * and specified number of backups and partitions.
      * <p>
-     * Note that {@code excludeNeighbors} parameter is ignored if {@code #getBackupFilter()} is set.
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
      *
      * @param exclNeighbors {@code True} if nodes residing on the same host may not act as backups
      *      of each other.
@@ -151,14 +159,14 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     /**
      * Initializes optional counts for replicas and backups.
      * <p>
-     * Note that {@code excludeNeighbors} parameter is ignored if {@code backupFilter} is set.
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
      *
      * @param parts Total number of partitions.
      * @param backupFilter Optional back up filter for nodes. If provided, backups will be selected
      *      from all nodes that pass this filter. First argument for this filter is primary node, and second
      *      argument is node being tested.
      * <p>
-     * Note that {@code excludeNeighbors} parameter is ignored if {@code backupFilter} is set.
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
      */
     public RendezvousAffinityFunction(int parts, @Nullable IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter) {
         this(false, parts, backupFilter);
@@ -173,7 +181,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
      */
     private RendezvousAffinityFunction(boolean exclNeighbors, int parts,
         IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter) {
-        A.ensure(parts != 0, "parts != 0");
+        A.ensure(parts > 0, "parts > 0");
 
         this.exclNeighbors = exclNeighbors;
         this.parts = parts;
@@ -253,7 +261,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
      * from all nodes that pass this filter. First node passed to this filter is primary node,
      * and second node is a node being tested.
      * <p>
-     * Note that {@code excludeNeighbors} parameter is ignored if {@code backupFilter} is set.
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
      *
      * @return Optional backup filter.
      */
@@ -266,7 +274,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
      * nodes that pass this filter. First node being passed to this filter is primary node,
      * and second node is a node being tested.
      * <p>
-     * Note that {@code excludeNeighbors} parameter is ignored if {@code backupFilter} is set.
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
      *
      * @param backupFilter Optional backup filter.
      */
@@ -277,7 +285,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     /**
      * Checks flag to exclude same-host-neighbors from being backups of each other (default is {@code false}).
      * <p>
-     * Note that {@code excludeNeighbors} parameter is ignored if {@code #getBackupFilter()} is set.
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
      *
      * @return {@code True} if nodes residing on the same host may not act as backups of each other.
      */
@@ -288,7 +296,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     /**
      * Sets flag to exclude same-host-neighbors from being backups of each other (default is {@code false}).
      * <p>
-     * Note that {@code excludeNeighbors} parameter is ignored if {@code #getBackupFilter()} is set.
+     * Note that {@code backupFilter} is ignored if {@code excludeNeighbors} is set to {@code true}.
      *
      * @param exclNeighbors {@code True} if nodes residing on the same host may not act as backups of each other.
      */
@@ -355,20 +363,9 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
 
         Collections.sort(lst, COMPARATOR);
 
-        int primaryAndBackups;
-
-        List<ClusterNode> res;
-
-        if (backups == Integer.MAX_VALUE) {
-            primaryAndBackups = Integer.MAX_VALUE;
-
-            res = new ArrayList<>();
-        }
-        else {
-            primaryAndBackups = backups + 1;
+        int primaryAndBackups = backups == Integer.MAX_VALUE ? nodes.size() : Math.min(backups + 1, nodes.size());
 
-            res = new ArrayList<>(primaryAndBackups);
-        }
+        List<ClusterNode> res = new ArrayList<>(primaryAndBackups);
 
         ClusterNode primary = lst.get(0).get2();
 
@@ -376,39 +373,38 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
 
         // Select backups.
         if (backups > 0) {
-            for (int i = 1; i < lst.size(); i++) {
+            for (int i = 1; i < lst.size() && res.size() < primaryAndBackups; i++) {
                 IgniteBiTuple<Long, ClusterNode> next = lst.get(i);
 
                 ClusterNode node = next.get2();
 
                 if (exclNeighbors) {
-                    Collection<ClusterNode> allNeighbors = allNeighbors(neighborhoodCache, res);
+                    Collection<ClusterNode> allNeighbors = GridCacheUtils.neighborsForNodes(neighborhoodCache, res);
 
                     if (!allNeighbors.contains(node))
                         res.add(node);
                 }
-                else {
-                    if (!res.contains(node) && (backupFilter == null || backupFilter.apply(primary, node)))
-                        res.add(next.get2());
-                }
-
-                if (res.size() == primaryAndBackups)
-                    break;
+                else if (backupFilter == null || backupFilter.apply(primary, node))
+                    res.add(next.get2());
             }
         }
 
         if (res.size() < primaryAndBackups && nodes.size() >= primaryAndBackups && exclNeighbors) {
-            // Need to iterate one more time in case if there are no nodes which pass exclude backups criteria.
-            for (int i = 1; i < lst.size(); i++) {
+            // Need to iterate again in case if there are no nodes which pass exclude neighbors backups criteria.
+            for (int i = 1; i < lst.size() && res.size() < primaryAndBackups; i++) {
                 IgniteBiTuple<Long, ClusterNode> next = lst.get(i);
 
                 ClusterNode node = next.get2();
 
                 if (!res.contains(node))
                     res.add(next.get2());
+            }
+
+            if (!exclNeighborsWarn) {
+                LT.warn(log, null, "Affinity function excludeNeighbors property is ignored " +
+                    "because topology has no enough nodes to assign backups.");
 
-                if (res.size() == primaryAndBackups)
-                    break;
+                exclNeighborsWarn = true;
             }
         }
 
@@ -437,7 +433,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
         List<List<ClusterNode>> assignments = new ArrayList<>(parts);
 
         Map<UUID, Collection<ClusterNode>> neighborhoodCache = exclNeighbors ?
-            neighbors(affCtx.currentTopologySnapshot()) : null;
+            GridCacheUtils.neighbors(affCtx.currentTopologySnapshot()) : null;
 
         for (int i = 0; i < parts; i++) {
             List<ClusterNode> partAssignment = assignPartition(i, affCtx.currentTopologySnapshot(), affCtx.backups(),
@@ -463,6 +459,7 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     }
 
     /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
     @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
         parts = in.readInt();
         exclNeighbors = in.readBoolean();
@@ -471,57 +468,6 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     }
 
     /**
-     * Builds neighborhood map for all nodes in snapshot.
-     *
-     * @param topSnapshot Topology snapshot.
-     * @return Neighbors map.
-     */
-    private Map<UUID, Collection<ClusterNode>> neighbors(Collection<ClusterNode> topSnapshot) {
-        Map<String, Collection<ClusterNode>> macMap = new HashMap<>(topSnapshot.size(), 1.0f);
-
-        // Group by mac addresses.
-        for (ClusterNode node : topSnapshot) {
-            String macs = node.attribute(IgniteNodeAttributes.ATTR_MACS);
-
-            Collection<ClusterNode> nodes = macMap.get(macs);
-
-            if (nodes == null) {
-                nodes = new HashSet<>();
-
-                macMap.put(macs, nodes);
-            }
-
-            nodes.add(node);
-        }
-
-        Map<UUID, Collection<ClusterNode>> neighbors = new HashMap<>(topSnapshot.size(), 1.0f);
-
-        for (Collection<ClusterNode> group : macMap.values()) {
-            for (ClusterNode node : group)
-                neighbors.put(node.id(), group);
-        }
-
-        return neighbors;
-    }
-
-    /**
-     * @param neighborhoodCache Neighborhood cache.
-     * @param nodes Nodes.
-     * @return All neighbors for given nodes.
-     */
-    private Collection<ClusterNode> allNeighbors(Map<UUID, Collection<ClusterNode>> neighborhoodCache,
-        Iterable<ClusterNode> nodes) {
-        Collection<ClusterNode> res = new HashSet<>();
-
-        for (ClusterNode node : nodes) {
-            if (!res.contains(node))
-                res.addAll(neighborhoodCache.get(node.id()));
-        }
-
-        return res;
-    }
-
-    /**
      *
      */
     private static class HashComparator implements Comparator<IgniteBiTuple<Long, ClusterNode>>, Serializable {

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 722e570..578ad6c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -53,7 +53,6 @@ import org.apache.ignite.cache.CacheRebalanceMode;
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cache.affinity.AffinityFunctionContext;
 import org.apache.ignite.cache.affinity.AffinityNodeAddressHashResolver;
-import org.apache.ignite.cache.affinity.fair.FairAffinityFunction;
 import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.CacheStoreSessionListener;
@@ -367,18 +366,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         CacheType cacheType,
         @Nullable CacheStore cfgStore) throws IgniteCheckedException {
         if (cc.getCacheMode() == REPLICATED) {
-            if (cc.getAffinity() instanceof FairAffinityFunction)
-                throw new IgniteCheckedException("REPLICATED cache can not be started with FairAffinityFunction" +
-                    " [cacheName=" + U.maskName(cc.getName()) + ']');
-
-            if (cc.getAffinity() instanceof RendezvousAffinityFunction) {
-                RendezvousAffinityFunction aff = (RendezvousAffinityFunction)cc.getAffinity();
-
-                if (aff.isExcludeNeighbors())
-                    throw new IgniteCheckedException("For REPLICATED cache flag 'excludeNeighbors' in " +
-                        "RendezvousAffinityFunction cannot be set [cacheName=" + U.maskName(cc.getName()) + ']');
-            }
-
             if (cc.getNearConfiguration() != null &&
                 ctx.discovery().cacheAffinityNode(ctx.discovery().localNode(), cc.getName())) {
                 U.warn(log, "Near cache cannot be used with REPLICATED cache, " +

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
index ee1f4a1..f7d115f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
@@ -27,6 +27,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -1811,4 +1812,53 @@ public class GridCacheUtils {
             }
         };
     }
+
+    /**
+     * Builds neighborhood map for all nodes in snapshot.
+     *
+     * @param topSnapshot Topology snapshot.
+     * @return Neighbors map.
+     */
+    public static Map<UUID, Collection<ClusterNode>> neighbors(Collection<ClusterNode> topSnapshot) {
+        Map<String, Collection<ClusterNode>> macMap = new HashMap<>(topSnapshot.size(), 1.0f);
+
+        // Group by mac addresses.
+        for (ClusterNode node : topSnapshot) {
+            String macs = node.attribute(IgniteNodeAttributes.ATTR_MACS);
+
+            Collection<ClusterNode> nodes = macMap.get(macs);
+
+            if (nodes == null)
+                macMap.put(macs, nodes = new HashSet<>());
+
+            nodes.add(node);
+        }
+
+        Map<UUID, Collection<ClusterNode>> neighbors = new HashMap<>(topSnapshot.size(), 1.0f);
+
+        for (Collection<ClusterNode> group : macMap.values())
+            for (ClusterNode node : group)
+                neighbors.put(node.id(), group);
+
+        return neighbors;
+    }
+
+    /**
+     * Returns neighbors for all {@code nodes}.
+     *
+     * @param neighborhood Neighborhood cache.
+     * @param nodes Nodes.
+     * @return All neighbors for given nodes.
+     */
+    public static Collection<ClusterNode> neighborsForNodes(Map<UUID, Collection<ClusterNode>> neighborhood,
+        Iterable<ClusterNode> nodes) {
+        Collection<ClusterNode> res = new HashSet<>();
+
+        for (ClusterNode node : nodes) {
+            if (!res.contains(node))
+                res.addAll(neighborhood.get(node.id()));
+        }
+
+        return res;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/AbstractAffinityFunctionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/AbstractAffinityFunctionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AbstractAffinityFunctionSelfTest.java
new file mode 100644
index 0000000..878d7d1
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AbstractAffinityFunctionSelfTest.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.events.DiscoveryEvent;
+import org.apache.ignite.events.EventType;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.affinity.GridAffinityFunctionContextImpl;
+import org.apache.ignite.testframework.GridTestNode;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ *
+ */
+public abstract class AbstractAffinityFunctionSelfTest extends GridCommonAbstractTest {
+    /** MAC prefix. */
+    private static final String MAC_PREF = "MAC";
+
+    /**
+     * Returns affinity function.
+     *
+     * @return Affinity function.
+     */
+    protected abstract AffinityFunction affinityFunction();
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNodeRemovedNoBackups() throws Exception {
+        checkNodeRemoved(0);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNodeRemovedOneBackup() throws Exception {
+        checkNodeRemoved(1);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNodeRemovedTwoBackups() throws Exception {
+        checkNodeRemoved(2);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNodeRemovedThreeBackups() throws Exception {
+        checkNodeRemoved(3);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRandomReassignmentNoBackups() throws Exception {
+        checkRandomReassignment(0);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRandomReassignmentOneBackup() throws Exception {
+        checkRandomReassignment(1);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRandomReassignmentTwoBackups() throws Exception {
+        checkRandomReassignment(2);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRandomReassignmentThreeBackups() throws Exception {
+        checkRandomReassignment(3);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    protected void checkNodeRemoved(int backups) throws Exception {
+        checkNodeRemoved(backups, 1, 1);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    protected void checkNodeRemoved(int backups, int neighborsPerHost, int neighborsPeriod) throws Exception {
+
+        AffinityFunction aff = affinityFunction();
+
+        int nodesCnt = 50;
+
+        List<ClusterNode> nodes = new ArrayList<>(nodesCnt);
+
+        List<List<ClusterNode>> prev = null;
+
+        for (int i = 0; i < nodesCnt; i++) {
+            info("======================================");
+            info("Assigning partitions: " + i);
+            info("======================================");
+
+            ClusterNode node = new GridTestNode(UUID.randomUUID());
+
+            if (neighborsPerHost > 0)
+                node.attribute(MAC_PREF + ((i / neighborsPeriod) % (nodesCnt / neighborsPerHost)));
+
+            nodes.add(node);
+
+            DiscoveryEvent discoEvt = new DiscoveryEvent(node, "", EventType.EVT_NODE_JOINED, node);
+
+            GridAffinityFunctionContextImpl ctx =
+                new GridAffinityFunctionContextImpl(nodes, prev, discoEvt, new AffinityTopologyVersion(i), backups);
+
+            List<List<ClusterNode>> assignment = aff.assignPartitions(ctx);
+
+            info("Assigned.");
+
+            verifyAssignment(assignment, backups, aff.partitions(), nodes.size());
+
+            prev = assignment;
+        }
+
+        info("======================================");
+        info("Will remove nodes.");
+        info("======================================");
+
+        for (int i = 0; i < nodesCnt - 1; i++) {
+            info("======================================");
+            info("Assigning partitions: " + i);
+            info("======================================");
+
+            ClusterNode rmv = nodes.remove(nodes.size() - 1);
+
+            DiscoveryEvent discoEvt = new DiscoveryEvent(rmv, "", EventType.EVT_NODE_LEFT, rmv);
+
+            List<List<ClusterNode>> assignment = aff.assignPartitions(
+                new GridAffinityFunctionContextImpl(nodes, prev, discoEvt, new AffinityTopologyVersion(i),
+                    backups));
+
+            info("Assigned.");
+
+            verifyAssignment(assignment, backups, aff.partitions(), nodes.size());
+
+            prev = assignment;
+        }
+    }
+
+    /**
+     * @param backups Backups.
+     */
+    protected void checkRandomReassignment(int backups) {
+        AffinityFunction aff = affinityFunction();
+
+        Random rnd = new Random();
+
+        int maxNodes = 50;
+
+        List<ClusterNode> nodes = new ArrayList<>(maxNodes);
+
+        List<List<ClusterNode>> prev = null;
+
+        int state = 0;
+
+        int i = 0;
+
+        while (true) {
+            boolean add;
+
+            if (nodes.size() < 2) {
+                // Returned back to one node?
+                if (state == 1)
+                    return;
+
+                add = true;
+            }
+            else if (nodes.size() == maxNodes) {
+                if (state == 0)
+                    state = 1;
+
+                add = false;
+            }
+            else {
+                // Nodes size in [2, maxNodes - 1].
+                if (state == 0)
+                    add = rnd.nextInt(3) != 0; // 66% to add, 33% to remove.
+                else
+                    add = rnd.nextInt(3) == 0; // 33% to add, 66% to remove.
+            }
+
+            DiscoveryEvent discoEvt;
+
+            if (add) {
+                ClusterNode addedNode = new GridTestNode(UUID.randomUUID());
+
+                nodes.add(addedNode);
+
+                discoEvt = new DiscoveryEvent(addedNode, "", EventType.EVT_NODE_JOINED, addedNode);
+            }
+            else {
+                ClusterNode rmvNode = nodes.remove(rnd.nextInt(nodes.size()));
+
+                discoEvt = new DiscoveryEvent(rmvNode, "", EventType.EVT_NODE_LEFT, rmvNode);
+            }
+
+            info("======================================");
+            info("Assigning partitions [iter=" + i + ", discoEvt=" + discoEvt + ", nodesSize=" + nodes.size() + ']');
+            info("======================================");
+
+            List<List<ClusterNode>> assignment = aff.assignPartitions(
+                new GridAffinityFunctionContextImpl(nodes, prev, discoEvt, new AffinityTopologyVersion(i),
+                    backups));
+
+            verifyAssignment(assignment, backups, aff.partitions(), nodes.size());
+
+            prev = assignment;
+
+            i++;
+        }
+    }
+
+
+    /**
+     * @param assignment Assignment to verify.
+     */
+    private void verifyAssignment(List<List<ClusterNode>> assignment, int keyBackups, int partsCnt, int topSize) {
+        Map<UUID, Collection<Integer>> mapping = new HashMap<>();
+
+        int ideal = Math.round((float)partsCnt / topSize * Math.min(keyBackups + 1, topSize));
+
+        for (int part = 0; part < assignment.size(); part++) {
+            for (ClusterNode node : assignment.get(part)) {
+                assert node != null;
+
+                Collection<Integer> parts = mapping.get(node.id());
+
+                if (parts == null) {
+                    parts = new HashSet<>();
+
+                    mapping.put(node.id(), parts);
+                }
+
+                assertTrue(parts.add(part));
+            }
+        }
+
+        int max = -1, min = Integer.MAX_VALUE;
+
+        for (Collection<Integer> parts : mapping.values()) {
+            max = Math.max(max, parts.size());
+            min = Math.min(min, parts.size());
+        }
+
+        log().warning("max=" + max + ", min=" + min + ", ideal=" + ideal + ", minDev=" + deviation(min, ideal) + "%, " +
+            "maxDev=" + deviation(max, ideal) + "%");
+    }
+
+    /**
+     * @param val Value.
+     * @param ideal Ideal.
+     */
+    private static int deviation(int val, int ideal) {
+        return Math.round(Math.abs(((float)val - ideal) / ideal * 100));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityClientNodeSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityClientNodeSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityClientNodeSelfTest.java
new file mode 100644
index 0000000..24704ed
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityClientNodeSelfTest.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity;
+
+import java.util.Collection;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.affinity.fair.FairAffinityFunction;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.IgniteNodeAttributes;
+import org.apache.ignite.lang.IgnitePredicate;
+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 static org.apache.ignite.cache.CacheMode.REPLICATED;
+
+/**
+ *
+ */
+public class AffinityClientNodeSelfTest extends GridCommonAbstractTest {
+    /** */
+    protected static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private static final int NODE_CNT = 4;
+
+    /** */
+    private static final String CACHE1 = "cache1";
+
+    /** */
+    private static final String CACHE2 = "cache2";
+
+    /** */
+    private static final String CACHE3 = "cache3";
+
+    /** */
+    private static final String CACHE4 = "cache4";
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder);
+
+        if (gridName.equals(getTestGridName(NODE_CNT - 1)))
+            cfg.setClientMode(true);
+
+        CacheConfiguration ccfg1 = new CacheConfiguration();
+
+        ccfg1.setBackups(1);
+        ccfg1.setName(CACHE1);
+        ccfg1.setAffinity(new RendezvousAffinityFunction());
+        ccfg1.setNodeFilter(new TestNodesFilter());
+
+        CacheConfiguration ccfg2 = new CacheConfiguration();
+
+        ccfg2.setBackups(1);
+        ccfg2.setName(CACHE2);
+        ccfg2.setAffinity(new RendezvousAffinityFunction());
+
+        CacheConfiguration ccfg3 = new CacheConfiguration();
+
+        ccfg3.setBackups(1);
+        ccfg3.setName(CACHE3);
+        ccfg3.setAffinity(new FairAffinityFunction());
+        ccfg3.setNodeFilter(new TestNodesFilter());
+
+        CacheConfiguration ccfg4 = new CacheConfiguration();
+
+        ccfg4.setCacheMode(REPLICATED);
+        ccfg4.setName(CACHE4);
+        ccfg4.setNodeFilter(new TestNodesFilter());
+
+        cfg.setCacheConfiguration(ccfg1, ccfg2, ccfg3, ccfg4);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        startGrids(NODE_CNT);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testClientNodeNotInAffinity() throws Exception {
+        checkCache(CACHE1, 2);
+
+        checkCache(CACHE2, 2);
+
+        checkCache(CACHE3, 2);
+
+        checkCache(CACHE4, 3);
+
+        Ignite client = ignite(NODE_CNT - 1);
+
+        CacheConfiguration ccfg = new CacheConfiguration();
+
+        ccfg.setBackups(0);
+
+        ccfg.setNodeFilter(new TestNodesFilter());
+
+        IgniteCache<Integer, Integer> cache = client.createCache(ccfg);
+
+        try {
+            checkCache(null, 1);
+        }
+        finally {
+            cache.destroy();
+        }
+
+        cache = client.createCache(ccfg, new NearCacheConfiguration());
+
+        try {
+            checkCache(null, 1);
+        }
+        finally {
+            cache.destroy();
+        }
+    }
+
+    /**
+     * @param cacheName Cache name.
+     * @param expNodes Expected number of nodes per partition.
+     */
+    private void checkCache(String cacheName, int expNodes) {
+        log.info("Test cache: " + cacheName);
+
+        Ignite client = ignite(NODE_CNT - 1);
+
+        assertTrue(client.configuration().isClientMode());
+
+        ClusterNode clientNode = client.cluster().localNode();
+
+        for (int i = 0; i < NODE_CNT; i++) {
+            Ignite ignite = ignite(i);
+
+            Affinity<Integer> aff = ignite.affinity(cacheName);
+
+            for (int part = 0; part < aff.partitions(); part++) {
+                Collection<ClusterNode> nodes = aff.mapPartitionToPrimaryAndBackups(part);
+
+                assertEquals(expNodes, nodes.size());
+
+                assertFalse(nodes.contains(clientNode));
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    private static class TestNodesFilter implements IgnitePredicate<ClusterNode> {
+        /** {@inheritDoc} */
+        @Override public boolean apply(ClusterNode clusterNode) {
+            Boolean attr = clusterNode.attribute(IgniteNodeAttributes.ATTR_CLIENT_MODE);
+
+            assertNotNull(attr);
+
+            assertFalse(attr);
+
+            return true;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionBackupFilterAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionBackupFilterAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionBackupFilterAbstractSelfTest.java
new file mode 100644
index 0000000..3bf41c1
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionBackupFilterAbstractSelfTest.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity;
+
+import java.util.Collection;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.lang.IgniteBiPredicate;
+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 static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
+
+/**
+ * Base tests of {@link AffinityFunction} implementations with user provided backup filter.
+ */
+public abstract class AffinityFunctionBackupFilterAbstractSelfTest extends GridCommonAbstractTest {
+    /** Ip finder. */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Backup count. */
+    private static final int BACKUPS = 1;
+
+    /** Split attribute name. */
+    private static final String SPLIT_ATTRIBUTE_NAME = "split-attribute";
+
+    /** Split attribute value. */
+    private String splitAttrVal;
+
+    /** Test backup filter. */
+    protected static final IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter =
+        new IgniteBiPredicate<ClusterNode, ClusterNode>() {
+            @Override public boolean apply(ClusterNode primary, ClusterNode backup) {
+                assert primary != null : "primary is null";
+                assert backup != null : "backup is null";
+
+                return !F.eq(primary.attribute(SPLIT_ATTRIBUTE_NAME), backup.attribute(SPLIT_ATTRIBUTE_NAME));
+            }
+        };
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        CacheConfiguration cacheCfg = defaultCacheConfiguration();
+
+        cacheCfg.setCacheMode(PARTITIONED);
+        cacheCfg.setBackups(BACKUPS);
+        cacheCfg.setAffinity(affinityFunction());
+        cacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+        cacheCfg.setRebalanceMode(SYNC);
+        cacheCfg.setAtomicityMode(TRANSACTIONAL);
+
+        TcpDiscoverySpi spi = new TcpDiscoverySpi();
+        spi.setIpFinder(IP_FINDER);
+
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setCacheConfiguration(cacheCfg);
+        cfg.setDiscoverySpi(spi);
+        cfg.setUserAttributes(F.asMap(SPLIT_ATTRIBUTE_NAME, splitAttrVal));
+
+        return cfg;
+    }
+
+    /**
+     * @return Affinity function for test.
+     */
+    protected abstract AffinityFunction affinityFunction();
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPartitionDistribution() throws Exception {
+        try {
+            for (int i = 0; i < 3; i++) {
+                splitAttrVal = "A";
+
+                startGrid(2 * i);
+
+                splitAttrVal = "B";
+
+                startGrid(2 * i + 1);
+
+                awaitPartitionMapExchange();
+
+                checkPartitions();
+            }
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("ConstantConditions")
+    private void checkPartitions() throws Exception {
+        AffinityFunction aff = cacheConfiguration(grid(0).configuration(), null).getAffinity();
+
+        int partCnt = aff.partitions();
+
+        IgniteCache<Object, Object> cache = grid(0).cache(null);
+
+        for (int i = 0; i < partCnt; i++) {
+            Collection<ClusterNode> nodes = affinity(cache).mapKeyToPrimaryAndBackups(i);
+
+            assertEquals(2, nodes.size());
+
+            ClusterNode primary = F.first(nodes);
+            ClusterNode backup = F.last(nodes);
+
+            assertFalse(F.eq(primary.attribute(SPLIT_ATTRIBUTE_NAME), backup.attribute(SPLIT_ATTRIBUTE_NAME)));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionExcludeNeighborsAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionExcludeNeighborsAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionExcludeNeighborsAbstractSelfTest.java
new file mode 100644
index 0000000..10cb5a5
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/AffinityFunctionExcludeNeighborsAbstractSelfTest.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteNodeAttributes;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteProductVersion;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode;
+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 static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheRebalanceMode.NONE;
+
+/**
+ * Partitioned affinity test.
+ */
+@SuppressWarnings({"PointlessArithmeticExpression", "FieldCanBeLocal"})
+public abstract class AffinityFunctionExcludeNeighborsAbstractSelfTest extends GridCommonAbstractTest {
+    /** Number of backups. */
+    private int backups = 2;
+
+    /** Number of girds. */
+    private int gridInstanceNum;
+
+    /** Ip finder. */
+    private TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(final String gridName) throws Exception {
+        IgniteConfiguration c = super.getConfiguration(gridName);
+
+        // Override node attributes in discovery spi.
+        TcpDiscoverySpi spi = new TcpDiscoverySpi() {
+            @Override public void setNodeAttributes(Map<String, Object> attrs,
+                IgniteProductVersion ver) {
+                super.setNodeAttributes(attrs, ver);
+
+                // Set unique mac addresses for every group of three nodes.
+                String macAddrs = "MOCK_MACS_" + (gridInstanceNum / 3);
+
+                attrs.put(IgniteNodeAttributes.ATTR_MACS, macAddrs);
+
+                gridInstanceNum++;
+            }
+        };
+
+        spi.setIpFinder(ipFinder);
+
+        c.setDiscoverySpi(spi);
+
+        CacheConfiguration cc = defaultCacheConfiguration();
+
+        cc.setCacheMode(PARTITIONED);
+
+        cc.setBackups(backups);
+
+        cc.setAffinity(affinityFunction());
+
+        cc.setRebalanceMode(NONE);
+
+        c.setCacheConfiguration(cc);
+
+        return c;
+    }
+
+    /**
+     * @return Affinity function for test.
+     */
+    protected abstract AffinityFunction affinityFunction();
+
+    /**
+     * @param aff Affinity.
+     * @param key Key.
+     * @return Nodes.
+     */
+    private static Collection<? extends ClusterNode> nodes(Affinity<Object> aff, Object key) {
+        return aff.mapKeyToPrimaryAndBackups(key);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAffinityMultiNode() throws Exception {
+        int grids = 9;
+
+        startGrids(grids);
+
+        try {
+            Object key = 12345;
+
+            int copies = backups + 1;
+
+            for (int i = 0; i < grids; i++) {
+                final Ignite g = grid(i);
+
+                Affinity<Object> aff = g.affinity(null);
+
+                List<TcpDiscoveryNode> top = new ArrayList<>();
+
+                for (ClusterNode node : g.cluster().nodes())
+                    top.add((TcpDiscoveryNode) node);
+
+                Collections.sort(top);
+
+                assertEquals(grids, top.size());
+
+                int idx = 1;
+
+                for (ClusterNode n : top) {
+                    assertEquals(idx, n.order());
+
+                    idx++;
+                }
+
+                Collection<? extends ClusterNode> affNodes = nodes(aff, key);
+
+                info("Affinity picture for grid [i=" + i + ", aff=" + U.toShortString(affNodes));
+
+                assertEquals(copies, affNodes.size());
+
+                Set<String> macs = new HashSet<>();
+
+                for (ClusterNode node : affNodes)
+                    macs.add((String)node.attribute(IgniteNodeAttributes.ATTR_MACS));
+
+                assertEquals(copies, macs.size());
+            }
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAffinitySingleNode() throws Exception {
+        Ignite g = startGrid();
+
+        try {
+            Object key = 12345;
+
+            Collection<? extends ClusterNode> affNodes = nodes(g.affinity(null), key);
+
+            info("Affinity picture for grid: " + U.toShortString(affNodes));
+
+            assertEquals(1, affNodes.size());
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+}
\ No newline at end of file


[19/31] ignite git commit: Merge remote-tracking branch 'apache/master'

Posted by ra...@apache.org.
Merge remote-tracking branch 'apache/master'


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

Branch: refs/heads/ignite-1790
Commit: 3ec52f36ba4ce4dd3ca4f36bbdd557657419465a
Parents: e12e184 5a18002
Author: ashutak <as...@gridgain.com>
Authored: Tue Oct 27 16:39:31 2015 +0300
Committer: ashutak <as...@gridgain.com>
Committed: Tue Oct 27 16:39:31 2015 +0300

----------------------------------------------------------------------
 .../ClientAbstractMultiThreadedSelfTest.java    |   3 +-
 .../affinity/fair/FairAffinityFunction.java     | 497 ++++++++++++++-----
 .../rendezvous/RendezvousAffinityFunction.java  | 140 ++----
 .../processors/cache/GridCacheProcessor.java    |  13 -
 .../processors/cache/GridCacheUtils.java        |  50 ++
 .../AbstractAffinityFunctionSelfTest.java       | 293 +++++++++++
 .../affinity/AffinityClientNodeSelfTest.java    | 194 ++++++++
 ...ityFunctionBackupFilterAbstractSelfTest.java | 138 +++++
 ...unctionExcludeNeighborsAbstractSelfTest.java | 182 +++++++
 .../affinity/IgniteClientNodeAffinityTest.java  | 194 --------
 .../fair/FairAffinityDynamicCacheSelfTest.java  |  97 ++++
 ...airAffinityFunctionBackupFilterSelfTest.java |  35 ++
 ...ffinityFunctionExcludeNeighborsSelfTest.java |  31 ++
 .../fair/FairAffinityFunctionNodesSelfTest.java | 245 +++++++++
 .../fair/FairAffinityFunctionSelfTest.java      |  31 ++
 .../GridFairAffinityFunctionNodesSelfTest.java  | 245 ---------
 .../fair/GridFairAffinityFunctionSelfTest.java  | 270 ----------
 .../IgniteFairAffinityDynamicCacheSelfTest.java |  97 ----
 ...ousAffinityFunctionBackupFilterSelfTest.java |  35 ++
 ...ffinityFunctionExcludeNeighborsSelfTest.java |  32 ++
 .../RendezvousAffinityFunctionSelfTest.java     |  50 ++
 .../cache/CrossCacheTxRandomOperationsTest.java |   2 +-
 .../GridCacheAbstractLocalStoreSelfTest.java    |   5 +
 ...idCacheConfigurationConsistencySelfTest.java |  17 -
 ...dCachePartitionedAffinityFilterSelfTest.java | 143 ------
 .../dht/GridCacheDhtPreloadPutGetSelfTest.java  |   3 +
 ...unctionExcludeNeighborsAbstractSelfTest.java | 184 -------
 ...ffinityFunctionExcludeNeighborsSelfTest.java |  32 --
 ...xcludeNeighborsMultiNodeFullApiSelfTest.java |  36 ++
 ...tedFairAffinityMultiNodeFullApiSelfTest.java |  35 ++
 ...xcludeNeighborsMultiNodeFullApiSelfTest.java |  36 ++
 ...dezvousAffinityMultiNodeFullApiSelfTest.java |  36 ++
 .../IgniteCacheFullApiSelfTestSuite.java        |   8 +
 .../ignite/testsuites/IgniteCacheTestSuite.java |  16 +-
 .../testsuites/IgniteCacheTestSuite2.java       |  12 +-
 .../cache/IgniteCacheAbstractQuerySelfTest.java |   4 +
 36 files changed, 2021 insertions(+), 1420 deletions(-)
----------------------------------------------------------------------



[31/31] ignite git commit: Merge branch 'master' into ignite-1790

Posted by ra...@apache.org.
Merge branch 'master' into ignite-1790


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

Branch: refs/heads/ignite-1790
Commit: 80bfe09b3c8f7e158b1cc8690cd03e5361cacd22
Parents: 1578a24 e769c3a
Author: Raul Kripalani <ra...@apache.org>
Authored: Wed Oct 28 12:06:19 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Wed Oct 28 12:06:19 2015 +0000

----------------------------------------------------------------------
 DEVNOTES.txt                                    |    3 +-
 .../ClientAbstractMultiThreadedSelfTest.java    |    3 +-
 .../apache/ignite/IgniteSystemProperties.java   |    9 +
 .../affinity/fair/FairAffinityFunction.java     |  497 +-
 .../rendezvous/RendezvousAffinityFunction.java  |  140 +-
 .../configuration/CacheConfiguration.java       |   28 +-
 .../configuration/TransactionConfiguration.java |    6 +-
 .../internal/GridEventConsumeHandler.java       |   19 +-
 .../apache/ignite/internal/IgniteKernal.java    |    2 +
 .../ignite/internal/IgniteNodeAttributes.java   |    3 +
 .../deployment/GridDeploymentLocalStore.java    |    8 +-
 .../GridDeploymentPerLoaderStore.java           |    8 +-
 .../GridDeploymentPerVersionStore.java          |    8 +-
 .../internal/portable/PortableContext.java      |   91 +-
 .../portable/api/PortableMarshaller.java        |    5 +
 .../processors/cache/CacheMetricsImpl.java      |   12 +-
 .../processors/cache/CacheObjectContext.java    |   17 +-
 .../processors/cache/GridCacheAdapter.java      |  459 +-
 .../processors/cache/GridCacheContext.java      |   10 +-
 .../processors/cache/GridCacheEntryEx.java      |   62 +-
 .../cache/GridCacheEvictionManager.java         |    5 +-
 .../cache/GridCacheEvictionRequest.java         |   18 +-
 .../cache/GridCacheEvictionResponse.java        |    7 +-
 .../processors/cache/GridCacheIoManager.java    |   34 +-
 .../processors/cache/GridCacheMapEntry.java     |  137 +-
 .../processors/cache/GridCacheMessage.java      |   72 +-
 .../processors/cache/GridCacheMvcc.java         |  143 +-
 .../cache/GridCacheMvccCandidate.java           |   26 +-
 .../processors/cache/GridCacheProcessor.java    |   26 -
 .../cache/GridCacheSharedContext.java           |    3 +
 .../processors/cache/GridCacheUtils.java        |   70 +-
 .../distributed/GridCacheTtlUpdateRequest.java  |    7 +-
 .../distributed/GridCacheTxRecoveryFuture.java  |    9 +-
 .../distributed/GridCacheTxRecoveryRequest.java |    8 +-
 .../GridCacheTxRecoveryResponse.java            |   10 +-
 .../distributed/GridDistributedBaseMessage.java |   16 +-
 .../distributed/GridDistributedCacheEntry.java  |   12 +-
 .../distributed/GridDistributedLockRequest.java |    8 +-
 .../GridDistributedLockResponse.java            |   20 +-
 .../GridDistributedTxFinishRequest.java         |    6 +-
 .../GridDistributedTxFinishResponse.java        |    7 +-
 .../GridDistributedTxPrepareRequest.java        |   13 +-
 .../GridDistributedTxPrepareResponse.java       |   12 +-
 .../GridDistributedTxRemoteAdapter.java         |   61 +-
 .../GridDistributedUnlockRequest.java           |    7 +-
 .../dht/CacheDistributedGetFutureAdapter.java   |  158 +
 .../dht/GridDhtAffinityAssignmentRequest.java   |    7 +-
 .../dht/GridDhtAffinityAssignmentResponse.java  |    7 +-
 .../distributed/dht/GridDhtCacheAdapter.java    |   20 +-
 .../distributed/dht/GridDhtCacheEntry.java      |   23 +-
 .../cache/distributed/dht/GridDhtGetFuture.java |  199 +-
 .../distributed/dht/GridDhtLockFuture.java      |   10 +-
 .../distributed/dht/GridDhtLockRequest.java     |    7 +-
 .../distributed/dht/GridDhtLockResponse.java    |   14 +-
 .../dht/GridDhtTransactionalCacheAdapter.java   |  127 +-
 .../distributed/dht/GridDhtTxFinishFuture.java  |    9 +-
 .../distributed/dht/GridDhtTxFinishRequest.java |    7 +-
 .../dht/GridDhtTxFinishResponse.java            |    2 +-
 .../cache/distributed/dht/GridDhtTxLocal.java   |    4 +-
 .../distributed/dht/GridDhtTxPrepareFuture.java |  118 +-
 .../dht/GridDhtTxPrepareRequest.java            |   28 +-
 .../dht/GridDhtTxPrepareResponse.java           |   13 +-
 .../distributed/dht/GridDhtUnlockRequest.java   |    7 +-
 .../dht/GridPartitionedGetFuture.java           |  182 +-
 .../dht/atomic/GridDhtAtomicCache.java          |   28 +-
 .../GridDhtAtomicDeferredUpdateResponse.java    |   12 +-
 .../dht/atomic/GridDhtAtomicUpdateFuture.java   |    6 +-
 .../dht/atomic/GridDhtAtomicUpdateRequest.java  |   25 +-
 .../dht/atomic/GridDhtAtomicUpdateResponse.java |   11 +-
 .../dht/atomic/GridNearAtomicUpdateFuture.java  |   12 +-
 .../dht/atomic/GridNearAtomicUpdateRequest.java |   33 +-
 .../atomic/GridNearAtomicUpdateResponse.java    |   11 +-
 .../dht/colocated/GridDhtColocatedCache.java    |  138 +-
 .../colocated/GridDhtColocatedLockFuture.java   |    9 +-
 .../dht/preloader/GridDhtForceKeysFuture.java   |    5 +-
 .../dht/preloader/GridDhtForceKeysRequest.java  |   35 +-
 .../dht/preloader/GridDhtForceKeysResponse.java |   11 +-
 .../GridDhtPartitionDemandMessage.java          |    5 +
 .../GridDhtPartitionSupplyMessage.java          |    9 +-
 .../preloader/GridDhtPartitionSupplyPool.java   |   10 +-
 .../GridDhtPartitionsAbstractMessage.java       |    7 +-
 .../dht/preloader/GridDhtPreloader.java         |    3 +-
 .../distributed/near/GridNearAtomicCache.java   |    2 -
 .../distributed/near/GridNearCacheAdapter.java  |   32 +-
 .../distributed/near/GridNearCacheEntry.java    |   81 +-
 .../distributed/near/GridNearGetFuture.java     |  345 +-
 .../distributed/near/GridNearGetRequest.java    |   15 +-
 .../distributed/near/GridNearGetResponse.java   |   12 +-
 .../distributed/near/GridNearLockFuture.java    |    3 +-
 .../distributed/near/GridNearLockRequest.java   |    8 +-
 .../distributed/near/GridNearLockResponse.java  |    8 +-
 ...arOptimisticSerializableTxPrepareFuture.java |  930 ++++
 .../near/GridNearOptimisticTxPrepareFuture.java |  255 +-
 ...ridNearOptimisticTxPrepareFutureAdapter.java |  222 +
 .../GridNearPessimisticTxPrepareFuture.java     |   11 +-
 .../near/GridNearTransactionalCache.java        |   22 +-
 .../near/GridNearTxFinishFuture.java            |   20 +-
 .../near/GridNearTxFinishRequest.java           |    7 +-
 .../near/GridNearTxFinishResponse.java          |    2 +-
 .../cache/distributed/near/GridNearTxLocal.java |  157 +-
 .../near/GridNearTxPrepareFutureAdapter.java    |   13 +-
 .../near/GridNearTxPrepareRequest.java          |    8 +-
 .../near/GridNearTxPrepareResponse.java         |    8 +-
 .../distributed/near/GridNearUnlockRequest.java |    7 +-
 .../cache/local/GridLocalCacheEntry.java        |   23 +-
 .../cache/local/GridLocalLockFuture.java        |    2 +
 .../local/atomic/GridLocalAtomicCache.java      |    9 -
 .../portable/CacheObjectPortableContext.java    |    6 +-
 .../CacheObjectPortableProcessorImpl.java       |    5 +-
 .../query/GridCacheDistributedQueryFuture.java  |    5 +-
 .../query/GridCacheDistributedQueryManager.java |   25 +-
 .../cache/query/GridCacheQueryRequest.java      |   46 +-
 .../cache/query/GridCacheQueryResponse.java     |   29 +-
 .../continuous/CacheContinuousQueryHandler.java |    8 +-
 .../continuous/CacheContinuousQueryManager.java |    6 +-
 .../cache/transactions/IgniteInternalTx.java    |    8 +-
 .../transactions/IgniteTransactionsImpl.java    |    6 -
 .../cache/transactions/IgniteTxAdapter.java     |  128 +-
 .../cache/transactions/IgniteTxEntry.java       |   59 +-
 .../cache/transactions/IgniteTxHandler.java     |   20 +-
 .../transactions/IgniteTxLocalAdapter.java      |  843 ++--
 .../cache/transactions/IgniteTxLocalEx.java     |   27 +-
 .../cache/transactions/IgniteTxManager.java     |  327 +-
 .../cache/version/GridCacheVersionManager.java  |   73 +-
 .../IgniteCacheObjectProcessorImpl.java         |    7 +-
 .../datastreamer/DataStreamerImpl.java          |    2 +-
 .../ignite/internal/util/lang/GridFunc.java     |    8 +-
 .../ignite/marshaller/AbstractMarshaller.java   |   12 +-
 .../ignite/marshaller/jdk/JdkMarshaller.java    |    7 +-
 .../optimized/OptimizedMarshaller.java          |   14 +-
 .../optimized/OptimizedMarshallerUtils.java     |   35 +-
 .../ignite/spi/discovery/tcp/ServerImpl.java    |   52 +
 .../apache/ignite/transactions/Transaction.java |    2 +-
 .../transactions/TransactionIsolation.java      |    3 +-
 .../AbstractAffinityFunctionSelfTest.java       |  293 ++
 .../affinity/AffinityClientNodeSelfTest.java    |  194 +
 ...ityFunctionBackupFilterAbstractSelfTest.java |  138 +
 ...unctionExcludeNeighborsAbstractSelfTest.java |  182 +
 .../affinity/IgniteClientNodeAffinityTest.java  |  194 -
 .../fair/FairAffinityDynamicCacheSelfTest.java  |   97 +
 ...airAffinityFunctionBackupFilterSelfTest.java |   35 +
 ...ffinityFunctionExcludeNeighborsSelfTest.java |   31 +
 .../fair/FairAffinityFunctionNodesSelfTest.java |  245 +
 .../fair/FairAffinityFunctionSelfTest.java      |   31 +
 .../GridFairAffinityFunctionNodesSelfTest.java  |  245 -
 .../fair/GridFairAffinityFunctionSelfTest.java  |  270 --
 .../IgniteFairAffinityDynamicCacheSelfTest.java |   97 -
 ...ousAffinityFunctionBackupFilterSelfTest.java |   35 +
 ...ffinityFunctionExcludeNeighborsSelfTest.java |   32 +
 .../RendezvousAffinityFunctionSelfTest.java     |   50 +
 .../GridDiscoveryManagerAttributesSelfTest.java |   44 +-
 .../cache/CacheNearReaderUpdateTest.java        |  388 ++
 .../CacheSerializableTransactionsTest.java      | 4295 ++++++++++++++++++
 .../cache/CrossCacheTxRandomOperationsTest.java |    8 +-
 .../GridCacheAbstractFailoverSelfTest.java      |   14 +-
 .../cache/GridCacheAbstractFullApiSelfTest.java |    4 +-
 .../GridCacheAbstractLocalStoreSelfTest.java    |    5 +
 .../GridCacheAbstractRemoveFailureTest.java     |   94 +-
 ...eAtomicEntryProcessorDeploymentSelfTest.java |  211 +
 .../GridCacheConcurrentTxMultiNodeTest.java     |    3 -
 .../GridCacheConditionalDeploymentSelfTest.java |  190 +
 ...idCacheConfigurationConsistencySelfTest.java |   17 -
 .../GridCacheDeploymentOffHeapSelfTest.java     |   17 +-
 .../cache/GridCacheDeploymentSelfTest.java      |   26 +-
 .../cache/GridCacheMvccFlagsTest.java           |    6 +-
 .../cache/GridCacheMvccPartitionedSelfTest.java |  164 +
 .../processors/cache/GridCacheMvccSelfTest.java |    3 +-
 .../processors/cache/GridCacheTestEntryEx.java  |   53 +-
 ...ctionalEntryProcessorDeploymentSelfTest.java |   31 +
 .../cache/IgniteCacheCreateRestartSelfTest.java |    2 +
 .../IgniteCacheEntryListenerAbstractTest.java   |   50 +-
 .../processors/cache/IgniteTxAbstractTest.java  |   42 +-
 .../IgniteTxMultiThreadedAbstractTest.java      |  106 +-
 ...IgnitePartitionedCountDownLatchSelfTest.java |    7 +-
 ...dCachePartitionedAffinityFilterSelfTest.java |  143 -
 ...onedNearDisabledTxMultiThreadedSelfTest.java |   31 +
 ...niteCacheClientNodeChangingTopologyTest.java |  170 +-
 .../dht/GridCacheDhtPreloadPutGetSelfTest.java  |    3 +
 .../IgniteCacheCrossCacheTxFailoverTest.java    |   19 +
 .../dht/IgniteCacheLockFailoverSelfTest.java    |   11 +
 ...eAtomicInvalidPartitionHandlingSelfTest.java |    6 +-
 ...unctionExcludeNeighborsAbstractSelfTest.java |  184 -
 .../near/GridCacheNearTxExceptionSelfTest.java  |    1 +
 ...CachePartitionedTxMultiThreadedSelfTest.java |   15 +-
 ...ffinityFunctionExcludeNeighborsSelfTest.java |   32 -
 ...xcludeNeighborsMultiNodeFullApiSelfTest.java |   36 +
 ...tedFairAffinityMultiNodeFullApiSelfTest.java |   35 +
 ...xcludeNeighborsMultiNodeFullApiSelfTest.java |   36 +
 ...dezvousAffinityMultiNodeFullApiSelfTest.java |   36 +
 .../DataStreamerUpdateAfterLoadTest.java        |  184 +
 .../loadtests/hashmap/GridHashMapLoadTest.java  |    6 +-
 .../communication/GridCacheMessageSelfTest.java |   17 +-
 .../inmemory/GridTestSwapSpaceSpi.java          |    8 +
 .../ignite/testframework/GridTestUtils.java     |   19 +-
 .../junits/common/GridCommonAbstractTest.java   |   19 +-
 .../ignite/testsuites/IgniteBasicTestSuite.java |    4 +-
 .../IgniteCacheFullApiSelfTestSuite.java        |    8 +
 .../ignite/testsuites/IgniteCacheTestSuite.java |   38 +-
 .../testsuites/IgniteCacheTestSuite2.java       |   14 +-
 .../testsuites/IgniteCacheTestSuite3.java       |    8 +-
 .../testsuites/IgniteCacheTestSuite5.java       |   40 +
 .../testsuites/IgniteP2PSelfTestSuite.java      |   16 +-
 .../p2p/CacheDeploymentEntryProcessor.java      |   35 +
 .../CacheDeploymentPortableEntryProcessor.java  |   35 +
 .../cache/IgniteCacheAbstractQuerySelfTest.java |    4 +
 modules/jms11/pom.xml                           |    2 +-
 .../apache/ignite/stream/mqtt/MqttStreamer.java |  386 +-
 .../stream/mqtt/IgniteMqttStreamerTest.java     |  142 +-
 .../mqtt/IgniteMqttStreamerTestSuite.java       |    4 +-
 modules/spark-2.10/pom.xml                      |    4 +-
 modules/spark/pom.xml                           |    4 +-
 .../config/benchmark-multicast.properties       |    5 +-
 .../IgniteAccountSerializableTxBenchmark.java   |   81 +
 .../cache/IgniteAccountTxAbstractBenchmark.java |   61 +
 .../cache/IgniteAccountTxBenchmark.java         |   74 +
 .../cache/IgniteCacheAbstractBenchmark.java     |    7 +-
 .../IgnitePutAllSerializableTxBenchmark.java    |   77 +
 .../ignite/yardstick/cache/model/Account.java   |   42 +
 parent/pom.xml                                  |    1 +
 219 files changed, 13192 insertions(+), 4264 deletions(-)
----------------------------------------------------------------------



[16/31] ignite git commit: Exclude neighbors flag for affinity functions. This closes #80

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/IgniteClientNodeAffinityTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/IgniteClientNodeAffinityTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/IgniteClientNodeAffinityTest.java
deleted file mode 100644
index 888904b..0000000
--- a/modules/core/src/test/java/org/apache/ignite/cache/affinity/IgniteClientNodeAffinityTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.cache.affinity;
-
-import java.util.Collection;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.affinity.fair.FairAffinityFunction;
-import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.configuration.NearCacheConfiguration;
-import org.apache.ignite.internal.IgniteNodeAttributes;
-import org.apache.ignite.lang.IgnitePredicate;
-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 static org.apache.ignite.cache.CacheMode.REPLICATED;
-
-/**
- *
- */
-public class IgniteClientNodeAffinityTest extends GridCommonAbstractTest {
-    /** */
-    protected static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
-
-    /** */
-    private static final int NODE_CNT = 4;
-
-    /** */
-    private static final String CACHE1 = "cache1";
-
-    /** */
-    private static final String CACHE2 = "cache2";
-
-    /** */
-    private static final String CACHE3 = "cache3";
-
-    /** */
-    private static final String CACHE4 = "cache4";
-
-    /** {@inheritDoc} */
-    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
-        IgniteConfiguration cfg = super.getConfiguration(gridName);
-
-        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder);
-
-        if (gridName.equals(getTestGridName(NODE_CNT - 1)))
-            cfg.setClientMode(true);
-
-        CacheConfiguration ccfg1 = new CacheConfiguration();
-
-        ccfg1.setBackups(1);
-        ccfg1.setName(CACHE1);
-        ccfg1.setAffinity(new RendezvousAffinityFunction());
-        ccfg1.setNodeFilter(new TestNodesFilter());
-
-        CacheConfiguration ccfg2 = new CacheConfiguration();
-
-        ccfg2.setBackups(1);
-        ccfg2.setName(CACHE2);
-        ccfg2.setAffinity(new RendezvousAffinityFunction());
-
-        CacheConfiguration ccfg3 = new CacheConfiguration();
-
-        ccfg3.setBackups(1);
-        ccfg3.setName(CACHE3);
-        ccfg3.setAffinity(new FairAffinityFunction());
-        ccfg3.setNodeFilter(new TestNodesFilter());
-
-        CacheConfiguration ccfg4 = new CacheConfiguration();
-
-        ccfg4.setCacheMode(REPLICATED);
-        ccfg4.setName(CACHE4);
-        ccfg4.setNodeFilter(new TestNodesFilter());
-
-        cfg.setCacheConfiguration(ccfg1, ccfg2, ccfg3, ccfg4);
-
-        return cfg;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        super.beforeTestsStarted();
-
-        startGrids(NODE_CNT);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTestsStopped() throws Exception {
-        stopAllGrids();
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testClientNodeNotInAffinity() throws Exception {
-        checkCache(CACHE1, 2);
-
-        checkCache(CACHE2, 2);
-
-        checkCache(CACHE3, 2);
-
-        checkCache(CACHE4, 3);
-
-        Ignite client = ignite(NODE_CNT - 1);
-
-        CacheConfiguration ccfg = new CacheConfiguration();
-
-        ccfg.setBackups(0);
-
-        ccfg.setNodeFilter(new TestNodesFilter());
-
-        IgniteCache<Integer, Integer> cache = client.createCache(ccfg);
-
-        try {
-            checkCache(null, 1);
-        }
-        finally {
-            cache.destroy();
-        }
-
-        cache = client.createCache(ccfg, new NearCacheConfiguration());
-
-        try {
-            checkCache(null, 1);
-        }
-        finally {
-            cache.destroy();
-        }
-    }
-
-    /**
-     * @param cacheName Cache name.
-     * @param expNodes Expected number of nodes per partition.
-     */
-    private void checkCache(String cacheName, int expNodes) {
-        log.info("Test cache: " + cacheName);
-
-        Ignite client = ignite(NODE_CNT - 1);
-
-        assertTrue(client.configuration().isClientMode());
-
-        ClusterNode clientNode = client.cluster().localNode();
-
-        for (int i = 0; i < NODE_CNT; i++) {
-            Ignite ignite = ignite(i);
-
-            Affinity<Integer> aff = ignite.affinity(cacheName);
-
-            for (int part = 0; part < aff.partitions(); part++) {
-                Collection<ClusterNode> nodes = aff.mapPartitionToPrimaryAndBackups(part);
-
-                assertEquals(expNodes, nodes.size());
-
-                assertFalse(nodes.contains(clientNode));
-            }
-        }
-    }
-
-    /**
-     *
-     */
-    private static class TestNodesFilter implements IgnitePredicate<ClusterNode> {
-        /** {@inheritDoc} */
-        @Override public boolean apply(ClusterNode clusterNode) {
-            Boolean attr = clusterNode.attribute(IgniteNodeAttributes.ATTR_CLIENT_MODE);
-
-            assertNotNull(attr);
-
-            assertFalse(attr);
-
-            return true;
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java
new file mode 100644
index 0000000..0b32320
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity.fair;
+
+import java.util.concurrent.Callable;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+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.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ *
+ */
+public class FairAffinityDynamicCacheSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    public FairAffinityDynamicCacheSelfTest(){
+        super(false);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setIpFinder(IP_FINDER);
+
+        cfg.getTransactionConfiguration().setTxSerializableEnabled(true);
+
+        cfg.setDiscoverySpi(disco);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        startGridsMultiThreaded(3);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testStartStopCache() throws Exception {
+        CacheConfiguration<Integer, Integer> cacheCfg = new CacheConfiguration<>();
+
+        cacheCfg.setCacheMode(CacheMode.PARTITIONED);
+        cacheCfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
+        cacheCfg.setBackups(1);
+        cacheCfg.setName("test");
+        cacheCfg.setAffinity(new FairAffinityFunction());
+
+        final IgniteCache<Integer, Integer> cache = ignite(0).createCache(cacheCfg);
+
+        for (int i = 0; i < 10_000; i++)
+            cache.put(i, i);
+
+        IgniteInternalFuture<Object> destFut = GridTestUtils.runAsync(new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                ignite(0).destroyCache(cache.getName());
+
+                return null;
+            }
+        });
+
+        destFut.get(2000L);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionBackupFilterSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionBackupFilterSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionBackupFilterSelfTest.java
new file mode 100644
index 0000000..eedc9e4
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionBackupFilterSelfTest.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity.fair;
+
+import org.apache.ignite.cache.affinity.AffinityFunction;
+import org.apache.ignite.cache.affinity.AffinityFunctionBackupFilterAbstractSelfTest;
+
+/**
+ * Tests backup filter for {@link FairAffinityFunction}.
+ */
+public class FairAffinityFunctionBackupFilterSelfTest extends AffinityFunctionBackupFilterAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected AffinityFunction affinityFunction() {
+        FairAffinityFunction aff = new FairAffinityFunction(false);
+
+        aff.setBackupFilter(backupFilter);
+
+        return aff;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionExcludeNeighborsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionExcludeNeighborsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionExcludeNeighborsSelfTest.java
new file mode 100644
index 0000000..4182cd3
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionExcludeNeighborsSelfTest.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity.fair;
+
+import org.apache.ignite.cache.affinity.AffinityFunction;
+import org.apache.ignite.cache.affinity.AffinityFunctionExcludeNeighborsAbstractSelfTest;
+
+/**
+ * Tests exclude neighbors flag for {@link FairAffinityFunction}.
+ */
+public class FairAffinityFunctionExcludeNeighborsSelfTest extends AffinityFunctionExcludeNeighborsAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected AffinityFunction affinityFunction() {
+        return new FairAffinityFunction(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionNodesSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionNodesSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionNodesSelfTest.java
new file mode 100644
index 0000000..7420a0d
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionNodesSelfTest.java
@@ -0,0 +1,245 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity.fair;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.TreeSet;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.IgniteKernal;
+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;
+
+/**
+ * Tests partition fair affinity in real grid.
+ */
+public class FairAffinityFunctionNodesSelfTest extends GridCommonAbstractTest {
+    /** IP finder. */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Number of backups. */
+    private int backups;
+
+    /** Number of partitions. */
+    private int parts = 512;
+
+    /** Add nodes test. */
+    private static final boolean[] ADD_ONLY = new boolean[] {true, true, true, true, true, true};
+
+    /** Add nodes test. */
+    private static final boolean[] ADD_REMOVE = new boolean[]
+        {
+            true,  true,  true,  true,  true, true,
+            false, false, false, false, false
+        };
+
+    /** */
+    private static final boolean[] MIXED1 = new boolean[]
+        {
+            // 1     2     3      2     3     4      3     4     5      4      3      2
+            true, true, true, false, true, true, false, true, true, false, false, false
+        };
+
+    /** */
+    private static final boolean[] MIXED2 = new boolean[]
+        {
+            // 1     2     3      2      1     2      1     2     3      2      1     2
+            true, true, true, false, false, true, false, true, true, false, false, true
+        };
+
+    /** */
+    private static final boolean[] MIXED3 = new boolean[]
+        {
+            // 1     2     3     4     5     6      5     6     7     8     9      8      7     8     9
+            true, true, true, true, true, true, false, true, true, true, true, false, false, true, true,
+            //  8      7      6
+            false, false, false
+        };
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        CacheConfiguration ccfg = cacheConfiguration();
+
+        cfg.setCacheConfiguration(ccfg);
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(discoSpi);
+
+        return cfg;
+    }
+
+    /**
+     * @return Cache configuration.
+     */
+    private CacheConfiguration cacheConfiguration() {
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        cfg.setBackups(backups);
+
+        cfg.setCacheMode(CacheMode.PARTITIONED);
+
+        cfg.setNearConfiguration(null);
+
+        cfg.setAffinity(new FairAffinityFunction(parts));
+
+        return cfg;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAdd() throws Exception {
+        checkSequence(ADD_ONLY);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAddRemove() throws Exception {
+        checkSequence(ADD_REMOVE);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testMixed1() throws Exception {
+        checkSequence(MIXED1);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testMixed2() throws Exception {
+        checkSequence(MIXED2);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testMixed3() throws Exception {
+        checkSequence(MIXED3);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void checkSequence(boolean[] seq) throws Exception {
+        for (int b = 0; b < 3; b++) {
+            backups = b;
+
+            info(">>>>>>>>>>>>>>>> Checking backups: " + backups);
+
+            checkSequence0(seq);
+
+            info(">>>>>>>>>>>>>>>> Finished check: " + backups);
+        }
+    }
+
+    /**
+     * @param seq Start/stop sequence.
+     * @throws Exception If failed.
+     */
+    private void checkSequence0(boolean[] seq) throws Exception {
+        try {
+            startGrid(0);
+
+            TreeSet<Integer> started = new TreeSet<>();
+
+            started.add(0);
+
+            int topVer = 1;
+
+            for (boolean start : seq) {
+                if (start) {
+                    int nextIdx = nextIndex(started);
+
+                    startGrid(nextIdx);
+
+                    started.add(nextIdx);
+                }
+                else {
+                    int idx = started.last();
+
+                    stopGrid(idx);
+
+                    started.remove(idx);
+                }
+
+                topVer++;
+
+                info("Grid 0: " + grid(0).localNode().id());
+
+                ((IgniteKernal)grid(0)).internalCache().context().affinity().affinityReadyFuture(topVer).get();
+
+                for (int i : started) {
+                    if (i != 0) {
+                        IgniteEx grid = grid(i);
+
+                        ((IgniteKernal)grid).internalCache().context().affinity().affinityReadyFuture(topVer).get();
+
+                        info("Grid " + i + ": " + grid.localNode().id());
+
+                        for (int part = 0; part < parts; part++) {
+                            List<ClusterNode> firstNodes = (List<ClusterNode>)grid(0).affinity(null)
+                                .mapPartitionToPrimaryAndBackups(part);
+
+                            List<ClusterNode> secondNodes = (List<ClusterNode>)grid.affinity(null)
+                                .mapPartitionToPrimaryAndBackups(part);
+
+                            assertEquals(firstNodes.size(), secondNodes.size());
+
+                            for (int n = 0; n < firstNodes.size(); n++)
+                                assertEquals(firstNodes.get(n), secondNodes.get(n));
+                        }
+                    }
+                }
+            }
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * First positive integer that is not present in started set.
+     *
+     * @param started Already started indices.
+     * @return First positive integer that is not present in started set.
+     */
+    private int nextIndex(Collection<Integer> started) {
+        assert started.contains(0);
+
+        for (int i = 1; i < 10000; i++) {
+            if (!started.contains(i))
+                return i;
+        }
+
+        throw new IllegalStateException();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionSelfTest.java
new file mode 100644
index 0000000..a79c9fc
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityFunctionSelfTest.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity.fair;
+
+import org.apache.ignite.cache.affinity.AbstractAffinityFunctionSelfTest;
+import org.apache.ignite.cache.affinity.AffinityFunction;
+
+/**
+ * Tests for {@link FairAffinityFunction}.
+ */
+public class FairAffinityFunctionSelfTest extends AbstractAffinityFunctionSelfTest {
+    /** {@inheritDoc} */
+    @Override protected AffinityFunction affinityFunction() {
+        return new FairAffinityFunction();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/GridFairAffinityFunctionNodesSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/GridFairAffinityFunctionNodesSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/GridFairAffinityFunctionNodesSelfTest.java
deleted file mode 100644
index cf57b66..0000000
--- a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/GridFairAffinityFunctionNodesSelfTest.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.cache.affinity.fair;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.TreeSet;
-import org.apache.ignite.cache.CacheMode;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteEx;
-import org.apache.ignite.internal.IgniteKernal;
-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;
-
-/**
- * Tests partition fair affinity in real grid.
- */
-public class GridFairAffinityFunctionNodesSelfTest extends GridCommonAbstractTest {
-    /** IP finder. */
-    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
-
-    /** Number of backups. */
-    private int backups;
-
-    /** Number of partitions. */
-    private int parts = 512;
-
-    /** Add nodes test. */
-    private static final boolean[] ADD_ONLY = new boolean[] {true, true, true, true, true, true};
-
-    /** Add nodes test. */
-    private static final boolean[] ADD_REMOVE = new boolean[]
-        {
-            true,  true,  true,  true,  true, true,
-            false, false, false, false, false
-        };
-
-    /** */
-    private static final boolean[] MIXED1 = new boolean[]
-        {
-            // 1     2     3      2     3     4      3     4     5      4      3      2
-            true, true, true, false, true, true, false, true, true, false, false, false
-        };
-
-    /** */
-    private static final boolean[] MIXED2 = new boolean[]
-        {
-            // 1     2     3      2      1     2      1     2     3      2      1     2
-            true, true, true, false, false, true, false, true, true, false, false, true
-        };
-
-    /** */
-    private static final boolean[] MIXED3 = new boolean[]
-        {
-            // 1     2     3     4     5     6      5     6     7     8     9      8      7     8     9
-            true, true, true, true, true, true, false, true, true, true, true, false, false, true, true,
-            //  8      7      6
-            false, false, false
-        };
-
-    /** {@inheritDoc} */
-    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
-        IgniteConfiguration cfg = super.getConfiguration(gridName);
-
-        CacheConfiguration ccfg = cacheConfiguration();
-
-        cfg.setCacheConfiguration(ccfg);
-
-        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
-
-        discoSpi.setIpFinder(IP_FINDER);
-
-        cfg.setDiscoverySpi(discoSpi);
-
-        return cfg;
-    }
-
-    /**
-     * @return Cache configuration.
-     */
-    private CacheConfiguration cacheConfiguration() {
-        CacheConfiguration cfg = new CacheConfiguration();
-
-        cfg.setBackups(backups);
-
-        cfg.setCacheMode(CacheMode.PARTITIONED);
-
-        cfg.setNearConfiguration(null);
-
-        cfg.setAffinity(new FairAffinityFunction(parts));
-
-        return cfg;
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testAdd() throws Exception {
-        checkSequence(ADD_ONLY);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testAddRemove() throws Exception {
-        checkSequence(ADD_REMOVE);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testMixed1() throws Exception {
-        checkSequence(MIXED1);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testMixed2() throws Exception {
-        checkSequence(MIXED2);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testMixed3() throws Exception {
-        checkSequence(MIXED3);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    private void checkSequence(boolean[] seq) throws Exception {
-        for (int b = 0; b < 3; b++) {
-            backups = b;
-
-            info(">>>>>>>>>>>>>>>> Checking backups: " + backups);
-
-            checkSequence0(seq);
-
-            info(">>>>>>>>>>>>>>>> Finished check: " + backups);
-        }
-    }
-
-    /**
-     * @param seq Start/stop sequence.
-     * @throws Exception If failed.
-     */
-    private void checkSequence0(boolean[] seq) throws Exception {
-        try {
-            startGrid(0);
-
-            TreeSet<Integer> started = new TreeSet<>();
-
-            started.add(0);
-
-            int topVer = 1;
-
-            for (boolean start : seq) {
-                if (start) {
-                    int nextIdx = nextIndex(started);
-
-                    startGrid(nextIdx);
-
-                    started.add(nextIdx);
-                }
-                else {
-                    int idx = started.last();
-
-                    stopGrid(idx);
-
-                    started.remove(idx);
-                }
-
-                topVer++;
-
-                info("Grid 0: " + grid(0).localNode().id());
-
-                ((IgniteKernal)grid(0)).internalCache().context().affinity().affinityReadyFuture(topVer).get();
-
-                for (int i : started) {
-                    if (i != 0) {
-                        IgniteEx grid = grid(i);
-
-                        ((IgniteKernal)grid).internalCache().context().affinity().affinityReadyFuture(topVer).get();
-
-                        info("Grid " + i + ": " + grid.localNode().id());
-
-                        for (int part = 0; part < parts; part++) {
-                            List<ClusterNode> firstNodes = (List<ClusterNode>)grid(0).affinity(null)
-                                .mapPartitionToPrimaryAndBackups(part);
-
-                            List<ClusterNode> secondNodes = (List<ClusterNode>)grid.affinity(null)
-                                .mapPartitionToPrimaryAndBackups(part);
-
-                            assertEquals(firstNodes.size(), secondNodes.size());
-
-                            for (int n = 0; n < firstNodes.size(); n++)
-                                assertEquals(firstNodes.get(n), secondNodes.get(n));
-                        }
-                    }
-                }
-            }
-        }
-        finally {
-            stopAllGrids();
-        }
-    }
-
-    /**
-     * First positive integer that is not present in started set.
-     *
-     * @param started Already started indices.
-     * @return First positive integer that is not present in started set.
-     */
-    private int nextIndex(Collection<Integer> started) {
-        assert started.contains(0);
-
-        for (int i = 1; i < 10000; i++) {
-            if (!started.contains(i))
-                return i;
-        }
-
-        throw new IllegalStateException();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/GridFairAffinityFunctionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/GridFairAffinityFunctionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/GridFairAffinityFunctionSelfTest.java
deleted file mode 100644
index e746b42..0000000
--- a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/GridFairAffinityFunctionSelfTest.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.cache.affinity.fair;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.UUID;
-import org.apache.ignite.cache.affinity.AffinityFunction;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.events.DiscoveryEvent;
-import org.apache.ignite.events.EventType;
-import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
-import org.apache.ignite.internal.processors.affinity.GridAffinityFunctionContextImpl;
-import org.apache.ignite.testframework.GridTestNode;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-
-/**
- *
- */
-public class GridFairAffinityFunctionSelfTest extends GridCommonAbstractTest {
-    /**
-     * @throws Exception If failed.
-     */
-    public void testNodeRemovedNoBackups() throws Exception {
-        checkNodeRemoved(0);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testNodeRemovedOneBackup() throws Exception {
-        checkNodeRemoved(1);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testNodeRemovedTwoBackups() throws Exception {
-        checkNodeRemoved(2);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testNodeRemovedThreeBackups() throws Exception {
-        checkNodeRemoved(3);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testRandomReassignmentNoBackups() throws Exception {
-        checkRandomReassignment(0);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testRandomReassignmentOneBackup() throws Exception {
-        checkRandomReassignment(1);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testRandomReassignmentTwoBackups() throws Exception {
-        checkRandomReassignment(2);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testRandomReassignmentThreeBackups() throws Exception {
-        checkRandomReassignment(3);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    private void checkNodeRemoved(int backups) throws Exception {
-        int parts = 256;
-
-        AffinityFunction aff = new FairAffinityFunction(parts);
-
-        int nodesCnt = 50;
-
-        List<ClusterNode> nodes = new ArrayList<>(nodesCnt);
-
-        List<List<ClusterNode>> prev = null;
-
-        for (int i = 0; i < nodesCnt; i++) {
-            info("======================================");
-            info("Assigning partitions: " + i);
-            info("======================================");
-
-            ClusterNode node = new GridTestNode(UUID.randomUUID());
-
-            nodes.add(node);
-
-            DiscoveryEvent discoEvt = new DiscoveryEvent(node, "", EventType.EVT_NODE_JOINED,
-                node);
-
-            List<List<ClusterNode>> assignment = aff.assignPartitions(
-                new GridAffinityFunctionContextImpl(nodes, prev, discoEvt, new AffinityTopologyVersion(i),
-                    backups));
-
-            info("Assigned.");
-
-            verifyAssignment(assignment, backups, parts, nodes.size());
-
-            prev = assignment;
-        }
-
-        info("======================================");
-        info("Will remove nodes.");
-        info("======================================");
-
-        for (int i = 0; i < nodesCnt - 1; i++) {
-            info("======================================");
-            info("Assigning partitions: " + i);
-            info("======================================");
-
-            ClusterNode rmv = nodes.remove(nodes.size() - 1);
-
-            DiscoveryEvent discoEvt = new DiscoveryEvent(rmv, "", EventType.EVT_NODE_LEFT, rmv);
-
-            List<List<ClusterNode>> assignment = aff.assignPartitions(
-                new GridAffinityFunctionContextImpl(nodes, prev, discoEvt, new AffinityTopologyVersion(i),
-                    backups));
-
-            info("Assigned.");
-
-            verifyAssignment(assignment, backups, parts, nodes.size());
-
-            prev = assignment;
-        }
-    }
-
-    @SuppressWarnings("IfMayBeConditional")
-    private void checkRandomReassignment(int backups) {
-        int parts = 256;
-
-        AffinityFunction aff = new FairAffinityFunction(parts);
-
-        Random rnd = new Random();
-
-        int maxNodes = 50;
-
-        List<ClusterNode> nodes = new ArrayList<>(maxNodes);
-
-        List<List<ClusterNode>> prev = null;
-
-        int state = 0;
-
-        int i = 0;
-
-        while (true) {
-            boolean add;
-
-            if (nodes.size() < 2) {
-                // Returned back to one node?
-                if (state == 1)
-                    return;
-
-                add = true;
-            }
-            else if (nodes.size() == maxNodes) {
-                if (state == 0)
-                    state = 1;
-
-                add = false;
-            }
-            else {
-                // Nodes size in [2, maxNodes - 1].
-                if (state == 0)
-                    add = rnd.nextInt(3) != 0; // 66% to add, 33% to remove.
-                else
-                    add = rnd.nextInt(3) == 0; // 33% to add, 66% to remove.
-            }
-
-            DiscoveryEvent discoEvt;
-
-            if (add) {
-                ClusterNode addedNode = new GridTestNode(UUID.randomUUID());
-
-                nodes.add(addedNode);
-
-                discoEvt = new DiscoveryEvent(addedNode, "", EventType.EVT_NODE_JOINED, addedNode);
-            }
-            else {
-                ClusterNode rmvNode = nodes.remove(rnd.nextInt(nodes.size()));
-
-                discoEvt = new DiscoveryEvent(rmvNode, "", EventType.EVT_NODE_LEFT, rmvNode);
-            }
-
-            info("======================================");
-            info("Assigning partitions [iter=" + i + ", discoEvt=" + discoEvt + ", nodesSize=" + nodes.size() + ']');
-            info("======================================");
-
-            List<List<ClusterNode>> assignment = aff.assignPartitions(
-                new GridAffinityFunctionContextImpl(nodes, prev, discoEvt, new AffinityTopologyVersion(i),
-                    backups));
-
-            verifyAssignment(assignment, backups, parts, nodes.size());
-
-            prev = assignment;
-
-            i++;
-        }
-    }
-
-    /**
-     * @param assignment Assignment to verify.
-     */
-    private void verifyAssignment(List<List<ClusterNode>> assignment, int keyBackups, int partsCnt, int topSize) {
-        Map<UUID, Collection<Integer>> mapping = new HashMap<>();
-
-        int ideal = Math.round((float)partsCnt / topSize * Math.min(keyBackups + 1, topSize));
-
-        for (int part = 0; part < assignment.size(); part++) {
-            for (ClusterNode node : assignment.get(part)) {
-                assert node != null;
-
-                Collection<Integer> parts = mapping.get(node.id());
-
-                if (parts == null) {
-                    parts = new HashSet<>();
-
-                    mapping.put(node.id(), parts);
-                }
-
-                assertTrue(parts.add(part));
-            }
-        }
-
-        int max = -1, min = Integer.MAX_VALUE;
-
-        for (Collection<Integer> parts : mapping.values()) {
-            max = Math.max(max, parts.size());
-            min = Math.min(min, parts.size());
-        }
-
-        log().warning("max=" + max + ", min=" + min + ", ideal=" + ideal + ", minDev=" + deviation(min, ideal) + "%, " +
-            "maxDev=" + deviation(max, ideal) + "%");
-    }
-
-    private static int deviation(int val, int ideal) {
-        return Math.round(Math.abs(((float)val - ideal) / ideal * 100));
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java
deleted file mode 100644
index eb1c455..0000000
--- a/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.cache.affinity.fair;
-
-import java.util.concurrent.Callable;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CacheAtomicityMode;
-import org.apache.ignite.cache.CacheMode;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteInternalFuture;
-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.GridTestUtils;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-
-/**
- *
- */
-public class IgniteFairAffinityDynamicCacheSelfTest extends GridCommonAbstractTest {
-    /** */
-    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
-
-    /** */
-    public IgniteFairAffinityDynamicCacheSelfTest(){
-        super(false);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
-        IgniteConfiguration cfg = super.getConfiguration(gridName);
-
-        TcpDiscoverySpi disco = new TcpDiscoverySpi();
-
-        disco.setIpFinder(IP_FINDER);
-
-        cfg.getTransactionConfiguration().setTxSerializableEnabled(true);
-
-        cfg.setDiscoverySpi(disco);
-
-        return cfg;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTestsStarted() throws Exception {
-        startGridsMultiThreaded(3);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTestsStopped() throws Exception {
-        stopAllGrids();
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testStartStopCache() throws Exception {
-        CacheConfiguration<Integer, Integer> cacheCfg = new CacheConfiguration<>();
-
-        cacheCfg.setCacheMode(CacheMode.PARTITIONED);
-        cacheCfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
-        cacheCfg.setBackups(1);
-        cacheCfg.setName("test");
-        cacheCfg.setAffinity(new FairAffinityFunction());
-
-        final IgniteCache<Integer, Integer> cache = ignite(0).createCache(cacheCfg);
-
-        for (int i = 0; i < 10_000; i++)
-            cache.put(i, i);
-
-        IgniteInternalFuture<Object> destFut = GridTestUtils.runAsync(new Callable<Object>() {
-            @Override public Object call() throws Exception {
-                ignite(0).destroyCache(cache.getName());
-
-                return null;
-            }
-        });
-
-        destFut.get(2000L);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionBackupFilterSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionBackupFilterSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionBackupFilterSelfTest.java
new file mode 100644
index 0000000..d5d8b8f
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionBackupFilterSelfTest.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity.rendezvous;
+
+import org.apache.ignite.cache.affinity.AffinityFunction;
+import org.apache.ignite.cache.affinity.AffinityFunctionBackupFilterAbstractSelfTest;
+
+/**
+ * Partitioned affinity test.
+ */
+public class RendezvousAffinityFunctionBackupFilterSelfTest extends AffinityFunctionBackupFilterAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected AffinityFunction affinityFunction() {
+        RendezvousAffinityFunction aff = new RendezvousAffinityFunction(false);
+
+        aff.setBackupFilter(backupFilter);
+
+        return aff;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionExcludeNeighborsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionExcludeNeighborsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionExcludeNeighborsSelfTest.java
new file mode 100644
index 0000000..ea47c68
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionExcludeNeighborsSelfTest.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity.rendezvous;
+
+import org.apache.ignite.cache.affinity.AffinityFunction;
+import org.apache.ignite.cache.affinity.AffinityFunctionExcludeNeighborsAbstractSelfTest;
+
+/**
+ * Tests exclude neighbors flag for rendezvous affinity function.
+ */
+public class RendezvousAffinityFunctionExcludeNeighborsSelfTest extends
+    AffinityFunctionExcludeNeighborsAbstractSelfTest {
+    /** {@inheritDoc} */
+    @Override protected AffinityFunction affinityFunction() {
+        return new RendezvousAffinityFunction(true);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionSelfTest.java
new file mode 100644
index 0000000..d895315
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunctionSelfTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.affinity.rendezvous;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.cache.affinity.AbstractAffinityFunctionSelfTest;
+import org.apache.ignite.cache.affinity.AffinityFunction;
+import org.apache.ignite.testframework.GridTestUtils;
+
+/**
+ * Tests for {@link RendezvousAffinityFunction}.
+ */
+public class RendezvousAffinityFunctionSelfTest extends AbstractAffinityFunctionSelfTest {
+    /** Ignite. */
+    private static Ignite ignite;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        ignite = startGrid();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected AffinityFunction affinityFunction() {
+        AffinityFunction aff = new RendezvousAffinityFunction();
+
+        GridTestUtils.setFieldValue(aff, "ignite", ignite);
+
+        return aff;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
index 1495a2b..cedb693 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
@@ -124,7 +124,7 @@ public class CrossCacheTxRandomOperationsTest extends GridCommonAbstractTest {
     /**
      * @throws Exception If failed.
      */
-    public void _testCrossCacheTxOperationsFairAffinity() throws Exception {
+    public void testCrossCacheTxOperationsFairAffinity() throws Exception {
         txOperations(PARTITIONED, FULL_SYNC, true, true);
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java
index a8d025c..3e12ebf 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java
@@ -37,6 +37,7 @@ import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMemoryMode;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
@@ -96,8 +97,12 @@ public abstract class GridCacheAbstractLocalStoreSelfTest extends GridCommonAbst
 
         CacheConfiguration cacheCfg = cache(gridName, null, 0);
 
+        cacheCfg.setAffinity(new RendezvousAffinityFunction());
+
         CacheConfiguration cacheBackupCfg = cache(gridName, BACKUP_CACHE, 2);
 
+        cacheBackupCfg.setAffinity(new RendezvousAffinityFunction());
+
         cfg.setCacheConfiguration(cacheCfg, cacheBackupCfg);
 
         TcpDiscoverySpi spi = new TcpDiscoverySpi();

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConfigurationConsistencySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConfigurationConsistencySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConfigurationConsistencySelfTest.java
index 31e34bb..e28e89f 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConfigurationConsistencySelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConfigurationConsistencySelfTest.java
@@ -806,23 +806,6 @@ public class GridCacheConfigurationConsistencySelfTest extends GridCommonAbstrac
     public void testAffinityForReplicatedCache() throws Exception {
         cacheEnabled = true;
 
-        aff = new FairAffinityFunction(); // Check cannot use FairAffinityFunction.
-
-        GridTestUtils.assertThrows(log, new Callable<Object>() {
-            @Override public Object call() throws Exception {
-                return startGrid(1);
-            }
-        }, IgniteCheckedException.class, null);
-
-        aff = new RendezvousAffinityFunction(true); // Check cannot set 'excludeNeighbors' flag.
-        backups = Integer.MAX_VALUE;
-
-        GridTestUtils.assertThrows(log, new Callable<Object>() {
-            @Override public Object call() throws Exception {
-                return startGrid(1);
-            }
-        }, IgniteCheckedException.class, null);
-
         aff = new RendezvousAffinityFunction(false, 100);
 
         startGrid(1);

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedAffinityFilterSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedAffinityFilterSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedAffinityFilterSelfTest.java
deleted file mode 100644
index cb8abec..0000000
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedAffinityFilterSelfTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.processors.cache.distributed;
-
-import java.util.Collection;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.cache.CacheWriteSynchronizationMode;
-import org.apache.ignite.cache.affinity.AffinityFunction;
-import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.lang.IgniteBiPredicate;
-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 static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
-import static org.apache.ignite.cache.CacheMode.PARTITIONED;
-import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
-
-/**
- * Partitioned affinity test.
- */
-@SuppressWarnings({"PointlessArithmeticExpression"})
-public class GridCachePartitionedAffinityFilterSelfTest extends GridCommonAbstractTest {
-    /** */
-    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
-
-    /** Backup count. */
-    private static final int BACKUPS = 1;
-
-    /** Split attribute name. */
-    private static final String SPLIT_ATTRIBUTE_NAME = "split-attribute";
-
-    /** Split attribute value. */
-    private String splitAttrVal;
-
-    /** Test backup filter. */
-    private static final IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter =
-        new IgniteBiPredicate<ClusterNode, ClusterNode>() {
-            @Override public boolean apply(ClusterNode primary, ClusterNode backup) {
-                assert primary != null : "primary is null";
-                assert backup != null : "backup is null";
-
-                return !F.eq(primary.attribute(SPLIT_ATTRIBUTE_NAME), backup.attribute(SPLIT_ATTRIBUTE_NAME));
-            }
-        };
-
-    /** {@inheritDoc} */
-    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
-        RendezvousAffinityFunction aff = new RendezvousAffinityFunction();
-
-        aff.setBackupFilter(backupFilter);
-
-        CacheConfiguration cacheCfg = defaultCacheConfiguration();
-
-        cacheCfg.setCacheMode(PARTITIONED);
-        cacheCfg.setBackups(BACKUPS);
-        cacheCfg.setAffinity(aff);
-        cacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
-        cacheCfg.setRebalanceMode(SYNC);
-        cacheCfg.setAtomicityMode(TRANSACTIONAL);
-
-        TcpDiscoverySpi spi = new TcpDiscoverySpi();
-
-        spi.setIpFinder(IP_FINDER);
-
-        IgniteConfiguration cfg = super.getConfiguration(gridName);
-
-        cfg.setCacheConfiguration(cacheCfg);
-        cfg.setDiscoverySpi(spi);
-
-        cfg.setUserAttributes(F.asMap(SPLIT_ATTRIBUTE_NAME, splitAttrVal));
-
-        return cfg;
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testPartitionDistribution() throws Exception {
-        try {
-            for (int i = 0; i < 3; i++) {
-                splitAttrVal = "A";
-
-                startGrid(2 * i);
-
-                splitAttrVal = "B";
-
-                startGrid(2 * i + 1);
-
-                awaitPartitionMapExchange();
-
-                checkPartitions();
-            }
-        }
-        finally {
-            stopAllGrids();
-        }
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    private void checkPartitions() throws Exception {
-        int partCnt = RendezvousAffinityFunction.DFLT_PARTITION_COUNT;
-
-        AffinityFunction aff = cacheConfiguration(grid(0).configuration(), null).getAffinity();
-
-        IgniteCache<Object, Object> cache = grid(0).cache(null);
-
-        for (int i = 0; i < partCnt; i++) {
-            assertEquals(i, aff.partition(i));
-
-            Collection<ClusterNode> nodes = affinity(cache).mapKeyToPrimaryAndBackups(i);
-
-            assertEquals(2, nodes.size());
-
-            ClusterNode primary = F.first(nodes);
-            ClusterNode backup = F.last(nodes);
-
-            assertFalse(F.eq(primary.attribute(SPLIT_ATTRIBUTE_NAME), backup.attribute(SPLIT_ATTRIBUTE_NAME)));
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheDhtPreloadPutGetSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheDhtPreloadPutGetSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheDhtPreloadPutGetSelfTest.java
index fa04b6b..c12e1ba 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheDhtPreloadPutGetSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheDhtPreloadPutGetSelfTest.java
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteInternalFuture;
@@ -76,6 +77,8 @@ public class GridCacheDhtPreloadPutGetSelfTest extends GridCommonAbstractTest {
         cacheCfg.setRebalanceMode(preloadMode);
         cacheCfg.setBackups(backups);
 
+        cacheCfg.setAffinity(new RendezvousAffinityFunction());
+
         TcpDiscoverySpi disco = new TcpDiscoverySpi();
 
         disco.setIpFinder(ipFinder);

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheAffinityFunctionExcludeNeighborsAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheAffinityFunctionExcludeNeighborsAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheAffinityFunctionExcludeNeighborsAbstractSelfTest.java
deleted file mode 100644
index 5b66174..0000000
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheAffinityFunctionExcludeNeighborsAbstractSelfTest.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.processors.cache.distributed.near;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.cache.affinity.Affinity;
-import org.apache.ignite.cache.affinity.AffinityFunction;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteNodeAttributes;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteProductVersion;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode;
-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 static org.apache.ignite.cache.CacheMode.PARTITIONED;
-import static org.apache.ignite.cache.CacheRebalanceMode.NONE;
-
-/**
- * Partitioned affinity test.
- */
-@SuppressWarnings({"PointlessArithmeticExpression", "FieldCanBeLocal"})
-public abstract class GridCacheAffinityFunctionExcludeNeighborsAbstractSelfTest extends GridCommonAbstractTest {
-    /** Number of backups. */
-    private int backups = 2;
-
-    /** */
-    private int gridInstanceNum;
-
-    /** */
-    private TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
-
-    /** {@inheritDoc} */
-    @Override protected IgniteConfiguration getConfiguration(final String gridName) throws Exception {
-        IgniteConfiguration c = super.getConfiguration(gridName);
-
-        // Override node attributes in discovery spi.
-        TcpDiscoverySpi spi = new TcpDiscoverySpi() {
-            @Override public void setNodeAttributes(Map<String, Object> attrs,
-                IgniteProductVersion ver) {
-                super.setNodeAttributes(attrs, ver);
-
-                // Set unique mac addresses for every group of three nodes.
-                String macAddrs = "MOCK_MACS_" + (gridInstanceNum / 3);
-
-                attrs.put(IgniteNodeAttributes.ATTR_MACS, macAddrs);
-
-                gridInstanceNum++;
-            }
-        };
-
-        spi.setIpFinder(ipFinder);
-
-        c.setDiscoverySpi(spi);
-
-        CacheConfiguration cc = defaultCacheConfiguration();
-
-        cc.setCacheMode(PARTITIONED);
-
-        cc.setBackups(backups);
-
-        cc.setAffinity(affinityFunction());
-
-        cc.setRebalanceMode(NONE);
-
-        c.setCacheConfiguration(cc);
-
-        return c;
-    }
-
-    /**
-     * @return Affinity function for test.
-     */
-    protected abstract AffinityFunction affinityFunction();
-
-    /**
-     * @param aff Affinity.
-     * @param key Key.
-     * @return Nodes.
-     */
-    private static Collection<? extends ClusterNode> nodes(Affinity<Object> aff, Object key) {
-        return aff.mapKeyToPrimaryAndBackups(key);
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testAffinityMultiNode() throws Exception {
-        int grids = 9;
-
-        startGrids(grids);
-
-        try {
-            Object key = 12345;
-
-            int copies = backups + 1;
-
-            for (int i = 0; i < grids; i++) {
-                final Ignite g = grid(i);
-
-                Affinity<Object> aff = g.affinity(null);
-
-                List<TcpDiscoveryNode> top = new ArrayList<>();
-
-                for (ClusterNode node : g.cluster().nodes())
-                    top.add((TcpDiscoveryNode) node);
-
-                Collections.sort(top);
-
-                assertEquals(grids, top.size());
-
-                int idx = 1;
-
-                for (ClusterNode n : top) {
-                    assertEquals(idx, n.order());
-
-                    idx++;
-                }
-
-                Collection<? extends ClusterNode> affNodes = nodes(aff, key);
-
-                info("Affinity picture for grid [i=" + i + ", aff=" + U.toShortString(affNodes));
-
-                assertEquals(copies, affNodes.size());
-
-                Set<String> macs = new HashSet<>();
-
-                for (ClusterNode node : affNodes)
-                    macs.add((String)node.attribute(IgniteNodeAttributes.ATTR_MACS));
-
-                assertEquals(copies, macs.size());
-            }
-        }
-        finally {
-            stopAllGrids();
-        }
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    public void testAffinitySingleNode() throws Exception {
-        Ignite g = startGrid();
-
-        try {
-            Object key = 12345;
-
-            Collection<? extends ClusterNode> affNodes = nodes(g.affinity(null), key);
-
-            info("Affinity picture for grid: " + U.toShortString(affNodes));
-
-            assertEquals(1, affNodes.size());
-        }
-        finally {
-            stopAllGrids();
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheRendezvousAffinityFunctionExcludeNeighborsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheRendezvousAffinityFunctionExcludeNeighborsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheRendezvousAffinityFunctionExcludeNeighborsSelfTest.java
deleted file mode 100644
index f26a1ef..0000000
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheRendezvousAffinityFunctionExcludeNeighborsSelfTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.processors.cache.distributed.near;
-
-import org.apache.ignite.cache.affinity.AffinityFunction;
-import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
-
-/**
- * Tests exclude neighbors flag for rendezvous affinity function.
- */
-public class GridCacheRendezvousAffinityFunctionExcludeNeighborsSelfTest extends
-    GridCacheAffinityFunctionExcludeNeighborsAbstractSelfTest {
-    /** {@inheritDoc} */
-    @Override protected AffinityFunction affinityFunction() {
-        return new RendezvousAffinityFunction(true);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedFairAffinityExcludeNeighborsMultiNodeFullApiSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedFairAffinityExcludeNeighborsMultiNodeFullApiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedFairAffinityExcludeNeighborsMultiNodeFullApiSelfTest.java
new file mode 100644
index 0000000..418449a
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedFairAffinityExcludeNeighborsMultiNodeFullApiSelfTest.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.replicated;
+
+import org.apache.ignite.cache.affinity.fair.FairAffinityFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+
+/**
+ * Multi-node tests for partitioned cache with {@link FairAffinityFunction}.
+ */
+public class CacheReplicatedFairAffinityExcludeNeighborsMultiNodeFullApiSelfTest
+    extends GridCacheReplicatedMultiNodeFullApiSelfTest {
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration cacheConfiguration(String gridName) throws Exception {
+        CacheConfiguration cfg = super.cacheConfiguration(gridName);
+
+        cfg.setAffinity(new FairAffinityFunction(true));
+
+        return cfg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedFairAffinityMultiNodeFullApiSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedFairAffinityMultiNodeFullApiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedFairAffinityMultiNodeFullApiSelfTest.java
new file mode 100644
index 0000000..ea65913
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedFairAffinityMultiNodeFullApiSelfTest.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.replicated;
+
+import org.apache.ignite.cache.affinity.fair.FairAffinityFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+
+/**
+ * Multi-node tests for partitioned cache with {@link FairAffinityFunction}.
+ */
+public class CacheReplicatedFairAffinityMultiNodeFullApiSelfTest extends GridCacheReplicatedMultiNodeFullApiSelfTest {
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration cacheConfiguration(String gridName) throws Exception {
+        CacheConfiguration cfg = super.cacheConfiguration(gridName);
+
+        cfg.setAffinity(new FairAffinityFunction(false));
+
+        return cfg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedRendezvousAffinityExcludeNeighborsMultiNodeFullApiSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedRendezvousAffinityExcludeNeighborsMultiNodeFullApiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedRendezvousAffinityExcludeNeighborsMultiNodeFullApiSelfTest.java
new file mode 100644
index 0000000..66aeefe
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedRendezvousAffinityExcludeNeighborsMultiNodeFullApiSelfTest.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.replicated;
+
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+
+/**
+ * Multi-node tests for partitioned cache with {@link RendezvousAffinityFunction}.
+ */
+public class CacheReplicatedRendezvousAffinityExcludeNeighborsMultiNodeFullApiSelfTest
+    extends GridCacheReplicatedMultiNodeFullApiSelfTest {
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration cacheConfiguration(String gridName) throws Exception {
+        CacheConfiguration cfg = super.cacheConfiguration(gridName);
+
+        cfg.setAffinity(new RendezvousAffinityFunction(true));
+
+        return cfg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedRendezvousAffinityMultiNodeFullApiSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedRendezvousAffinityMultiNodeFullApiSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedRendezvousAffinityMultiNodeFullApiSelfTest.java
new file mode 100644
index 0000000..c6900a5
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/CacheReplicatedRendezvousAffinityMultiNodeFullApiSelfTest.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.replicated;
+
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.configuration.CacheConfiguration;
+
+/**
+ * Multi-node tests for partitioned cache with {@link RendezvousAffinityFunction}.
+ */
+public class CacheReplicatedRendezvousAffinityMultiNodeFullApiSelfTest
+    extends GridCacheReplicatedMultiNodeFullApiSelfTest {
+    /** {@inheritDoc} */
+    @Override protected CacheConfiguration cacheConfiguration(String gridName) throws Exception {
+        CacheConfiguration cfg = super.cacheConfiguration(gridName);
+
+        cfg.setAffinity(new RendezvousAffinityFunction());
+
+        return cfg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheFullApiSelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheFullApiSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheFullApiSelfTestSuite.java
index c2f27fe..29109be 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheFullApiSelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheFullApiSelfTestSuite.java
@@ -77,6 +77,10 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePar
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedOffHeapMultiNodeFullApiSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedOffHeapTieredFullApiSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedOffHeapTieredMultiNodeFullApiSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.replicated.CacheReplicatedFairAffinityExcludeNeighborsMultiNodeFullApiSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.replicated.CacheReplicatedFairAffinityMultiNodeFullApiSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.replicated.CacheReplicatedRendezvousAffinityExcludeNeighborsMultiNodeFullApiSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.replicated.CacheReplicatedRendezvousAffinityMultiNodeFullApiSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCachePartitionedFairAffinityMultiNodeFullApiSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedAtomicFullApiSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedAtomicMultiNodeFullApiSelfTest;
@@ -175,6 +179,10 @@ public class IgniteCacheFullApiSelfTestSuite extends TestSuite {
         suite.addTestSuite(GridCacheAtomicNearOnlyMultiNodeFullApiSelfTest.class);
         suite.addTestSuite(GridCacheAtomicNearOnlyMultiNodeP2PDisabledFullApiSelfTest.class);
 
+        suite.addTestSuite(CacheReplicatedFairAffinityExcludeNeighborsMultiNodeFullApiSelfTest.class);
+        suite.addTestSuite(CacheReplicatedFairAffinityMultiNodeFullApiSelfTest.class);
+        suite.addTestSuite(CacheReplicatedRendezvousAffinityExcludeNeighborsMultiNodeFullApiSelfTest.class);
+        suite.addTestSuite(CacheReplicatedRendezvousAffinityMultiNodeFullApiSelfTest.class);
         suite.addTestSuite(GridCachePartitionedFairAffinityMultiNodeFullApiSelfTest.class);
         suite.addTestSuite(GridCachePartitionedNearDisabledFairAffinityMultiNodeFullApiSelfTest.class);
         suite.addTestSuite(GridCacheAtomicFairAffinityMultiNodeFullApiSelfTest.class);


[09/31] ignite git commit: ignite-1272: support of custom class loaders and conditional deployment info for portable marshaller and portable caches

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryManager.java
index 4422952..578f6de 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryManager.java
@@ -207,7 +207,8 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
                         cctx.cacheId(),
                         req.id(),
                         new IgniteCheckedException("Received request for incorrect cache [expected=" + cctx.name() +
-                            ", actual=" + req.cacheName()));
+                            ", actual=" + req.cacheName()),
+                        cctx.deploymentEnabled());
 
                     sendQueryResponse(sndId, res, 0);
                 }
@@ -228,7 +229,8 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
                     catch (Throwable e) {
                         U.error(log(), "Failed to run query.", e);
 
-                        sendQueryResponse(sndId, new GridCacheQueryResponse(cctx.cacheId(), req.id(), e.getCause()), 0);
+                        sendQueryResponse(sndId, new GridCacheQueryResponse(cctx.cacheId(), req.id(), e.getCause(),
+                            cctx.deploymentEnabled()), 0);
 
                         if (e instanceof Error)
                             throw (Error)e;
@@ -445,7 +447,7 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
                 fut.onPage(null, null, e, true);
             else
                 sendQueryResponse(qryInfo.senderId(),
-                    new GridCacheQueryResponse(cctx.cacheId(), qryInfo.requestId(), e),
+                    new GridCacheQueryResponse(cctx.cacheId(), qryInfo.requestId(), e, cctx.deploymentEnabled()),
                     qryInfo.query().timeout());
 
             return true;
@@ -455,7 +457,7 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
             fut.onPage(null, data, null, finished);
         else {
             GridCacheQueryResponse res = new GridCacheQueryResponse(cctx.cacheId(), qryInfo.requestId(),
-                /*finished*/false, /*fields*/false);
+                /*finished*/false, /*fields*/false, cctx.deploymentEnabled());
 
             res.data(data);
             res.finished(finished);
@@ -484,7 +486,7 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
             }
             else
                 sendQueryResponse(qryInfo.senderId(),
-                    new GridCacheQueryResponse(cctx.cacheId(), qryInfo.requestId(), e),
+                    new GridCacheQueryResponse(cctx.cacheId(), qryInfo.requestId(), e, cctx.deploymentEnabled()),
                     qryInfo.query().timeout());
 
             return true;
@@ -497,7 +499,7 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
         }
         else {
             GridCacheQueryResponse res = new GridCacheQueryResponse(cctx.cacheId(), qryInfo.requestId(),
-                finished, qryInfo.reducer() == null);
+                finished, qryInfo.reducer() == null, cctx.deploymentEnabled());
 
             res.metadata(metadata);
             res.data(entities != null ? entities : data);
@@ -567,7 +569,8 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
                 qry.query().keepPortable(),
                 qry.query().subjectId(),
                 qry.query().taskHash(),
-                queryTopologyVersion());
+                queryTopologyVersion(),
+                cctx.deploymentEnabled());
 
             addQueryFuture(req.id(), fut);
 
@@ -612,7 +615,8 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
                 qry.keepPortable(),
                 qry.subjectId(),
                 qry.taskHash(),
-                queryTopologyVersion());
+                queryTopologyVersion(),
+                cctx.deploymentEnabled());
 
             sendRequest(fut, req, nodes);
         }
@@ -678,7 +682,8 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
                 qry.query().keepPortable(),
                 qry.query().subjectId(),
                 qry.query().taskHash(),
-                queryTopologyVersion());
+                queryTopologyVersion(),
+                cctx.deploymentEnabled());
 
             addQueryFuture(req.id(), fut);
 
@@ -823,4 +828,4 @@ public class GridCacheDistributedQueryManager<K, V> extends GridCacheQueryManage
             return S.toString(CancelMessageId.class, this);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryRequest.java
index c9ce933..c7feda4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryRequest.java
@@ -139,15 +139,18 @@ public class GridCacheQueryRequest extends GridCacheMessage implements GridCache
      * @param id Request to cancel.
      * @param fields Fields query flag.
      * @param topVer Topology version.
+     * @param addDepInfo Deployment info flag.
      */
     public GridCacheQueryRequest(int cacheId,
         long id,
         boolean fields,
-        AffinityTopologyVersion topVer) {
+        AffinityTopologyVersion topVer,
+        boolean addDepInfo) {
         this.cacheId = cacheId;
         this.id = id;
         this.fields = fields;
         this.topVer = topVer;
+        this.addDepInfo = addDepInfo;
 
         cancel = true;
     }
@@ -166,6 +169,7 @@ public class GridCacheQueryRequest extends GridCacheMessage implements GridCache
      * @param subjId Subject ID.
      * @param taskHash Task name hash code.
      * @param topVer Topology version.
+     * @param addDepInfo Deployment info flag.
      */
     public GridCacheQueryRequest(
         int cacheId,
@@ -178,7 +182,8 @@ public class GridCacheQueryRequest extends GridCacheMessage implements GridCache
         boolean keepPortable,
         UUID subjId,
         int taskHash,
-        AffinityTopologyVersion topVer
+        AffinityTopologyVersion topVer,
+        boolean addDepInfo
     ) {
         this.cacheId = cacheId;
         this.id = id;
@@ -191,6 +196,7 @@ public class GridCacheQueryRequest extends GridCacheMessage implements GridCache
         this.subjId = subjId;
         this.taskHash = taskHash;
         this.topVer = topVer;
+        this.addDepInfo = addDepInfo;
     }
 
     /**
@@ -213,6 +219,7 @@ public class GridCacheQueryRequest extends GridCacheMessage implements GridCache
      * @param subjId Subject ID.
      * @param taskHash Task name hash code.
      * @param topVer Topology version.
+     * @param addDepInfo Deployment info flag.
      */
     public GridCacheQueryRequest(
         int cacheId,
@@ -233,7 +240,8 @@ public class GridCacheQueryRequest extends GridCacheMessage implements GridCache
         boolean keepPortable,
         UUID subjId,
         int taskHash,
-        AffinityTopologyVersion topVer
+        AffinityTopologyVersion topVer,
+        boolean addDepInfo
     ) {
         assert type != null || fields;
         assert clause != null || (type == SCAN || type == SET || type == SPI);
@@ -258,6 +266,7 @@ public class GridCacheQueryRequest extends GridCacheMessage implements GridCache
         this.subjId = subjId;
         this.taskHash = taskHash;
         this.topVer = topVer;
+        this.addDepInfo = addDepInfo;
     }
 
     /** {@inheritDoc} */
@@ -269,34 +278,36 @@ public class GridCacheQueryRequest extends GridCacheMessage implements GridCache
     @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
         super.prepareMarshal(ctx);
 
+        GridCacheContext cctx = ctx.cacheContext(cacheId);
+
         if (keyValFilter != null) {
-            if (ctx.deploymentEnabled())
-                prepareObject(keyValFilter, ctx);
+            if (addDepInfo)
+                prepareObject(keyValFilter, cctx);
 
-            keyValFilterBytes = CU.marshal(ctx, keyValFilter);
+            keyValFilterBytes = CU.marshal(cctx, keyValFilter);
         }
 
         if (rdc != null) {
-            if (ctx.deploymentEnabled())
-                prepareObject(rdc, ctx);
+            if (addDepInfo)
+                prepareObject(rdc, cctx);
 
-            rdcBytes = CU.marshal(ctx, rdc);
+            rdcBytes = CU.marshal(cctx, rdc);
         }
 
         if (trans != null) {
-            if (ctx.deploymentEnabled())
-                prepareObject(trans, ctx);
+            if (addDepInfo)
+                prepareObject(trans, cctx);
 
-            transBytes = CU.marshal(ctx, trans);
+            transBytes = CU.marshal(cctx, trans);
         }
 
         if (!F.isEmpty(args)) {
-            if (ctx.deploymentEnabled()) {
+            if (addDepInfo) {
                 for (Object arg : args)
-                    prepareObject(arg, ctx);
+                    prepareObject(arg, cctx);
             }
 
-            argsBytes = CU.marshal(ctx, args);
+            argsBytes = CU.marshal(cctx, args);
         }
     }
 
@@ -319,6 +330,11 @@ public class GridCacheQueryRequest extends GridCacheMessage implements GridCache
             args = mrsh.unmarshal(argsBytes, ldr);
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
     /**
      * @param ctx Context.
      * @throws IgniteCheckedException In case of error.

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryResponse.java
index 78e2ac7..cce465b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryResponse.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.GridDirectCollection;
 import org.apache.ignite.internal.GridDirectTransient;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheDeployable;
 import org.apache.ignite.internal.processors.cache.GridCacheMessage;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
@@ -89,23 +90,28 @@ public class GridCacheQueryResponse extends GridCacheMessage implements GridCach
      * @param reqId Request id.
      * @param finished Last response or not.
      * @param fields Fields query or not.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridCacheQueryResponse(int cacheId, long reqId, boolean finished, boolean fields) {
+    public GridCacheQueryResponse(int cacheId, long reqId, boolean finished, boolean fields, boolean addDepInfo) {
         this.cacheId = cacheId;
         this.reqId = reqId;
         this.finished = finished;
         this.fields = fields;
+        this.addDepInfo = addDepInfo;
     }
 
     /**
      * @param cacheId Cache ID.
      * @param reqId Request id.
      * @param err Error.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridCacheQueryResponse(int cacheId, long reqId, Throwable err) {
+    public GridCacheQueryResponse(int cacheId, long reqId, Throwable err, boolean addDepInfo) {
         this.cacheId = cacheId;
         this.reqId = reqId;
         this.err = err;
+        this.addDepInfo = addDepInfo;
+
         finished = true;
     }
 
@@ -114,19 +120,21 @@ public class GridCacheQueryResponse extends GridCacheMessage implements GridCach
     @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
         super.prepareMarshal(ctx);
 
+        GridCacheContext cctx = ctx.cacheContext(cacheId);
+
         if (err != null)
             errBytes = ctx.marshaller().marshal(err);
 
-        metaDataBytes = marshalCollection(metadata, ctx);
-        dataBytes = marshalCollection(data, ctx);
+        metaDataBytes = marshalCollection(metadata, cctx);
+        dataBytes = marshalCollection(data, cctx);
 
-        if (ctx.deploymentEnabled() && !F.isEmpty(data)) {
+        if (addDepInfo && !F.isEmpty(data)) {
             for (Object o : data) {
                 if (o instanceof Map.Entry) {
                     Map.Entry e = (Map.Entry)o;
 
-                    prepareObject(e.getKey(), ctx);
-                    prepareObject(e.getValue(), ctx);
+                    prepareObject(e.getKey(), cctx);
+                    prepareObject(e.getValue(), cctx);
                 }
             }
         }
@@ -143,6 +151,11 @@ public class GridCacheQueryResponse extends GridCacheMessage implements GridCach
         data = unmarshalCollection(dataBytes, ctx, ldr);
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
     /**
      * @return Metadata.
      */
@@ -339,4 +352,4 @@ public class GridCacheQueryResponse extends GridCacheMessage implements GridCach
     @Override public String toString() {
         return S.toString(GridCacheQueryResponse.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
index 1990e18..e517c70 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java
@@ -233,12 +233,10 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
                         locLsnr.onUpdated(F.<CacheEntryEvent<? extends K, ? extends V>>asList(evt));
                     else {
                         try {
-                            if (ctx.config().isPeerClassLoadingEnabled() && ctx.discovery().node(nodeId) != null) {
+                            if (cctx.deploymentEnabled() && ctx.discovery().node(nodeId) != null) {
                                 evt.entry().prepareMarshal(cctx);
 
-                                GridCacheDeploymentManager depMgr = cctx.deploy();
-
-                                depMgr.prepare(evt.entry());
+                                cctx.deploy().prepare(evt.entry());
                             }
                             else
                                 evt.entry().prepareMarshal(cctx);
@@ -551,4 +549,4 @@ class CacheContinuousQueryHandler<K, V> implements GridContinuousHandler {
             depInfo = (GridDeploymentInfo)in.readObject();
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
index 11cd3fd..20fb8c2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
@@ -280,6 +280,12 @@ public interface IgniteInternalTx extends AutoCloseable, GridTimeoutObject {
     public Collection<Integer> activeCacheIds();
 
     /**
+     * @return {@code true} or {@code false} if the deployment is enabled or disabled for all active caches involved
+     * in this transaction.
+     */
+    public boolean activeCachesDeploymentEnabled();
+
+    /**
      * Attempts to set topology version and returns the current value.
      * If topology version was previously set, then it's value will
      * be returned (but not updated).
@@ -722,4 +728,4 @@ public interface IgniteInternalTx extends AutoCloseable, GridTimeoutObject {
      * @param topVer New topology version.
      */
     public void onRemap(AffinityTopologyVersion topVer);
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index 88752a2..7d7e3e8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -1757,6 +1757,11 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
         }
 
         /** {@inheritDoc} */
+        @Override public boolean activeCachesDeploymentEnabled() {
+            return false;
+        }
+
+        /** {@inheritDoc} */
         @Nullable @Override public Object addMeta(int key, Object val) {
             throw new IllegalStateException("Deserialized transaction can only be used as read-only.");
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 3c33d19..2462dda 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
@@ -735,13 +735,13 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
         if (filters != null) {
             for (CacheEntryPredicate p : filters) {
                 if (p != null)
-                    p.prepareMarshal(ctx.cacheContext(cacheId));
+                    p.prepareMarshal(this.ctx);
             }
         }
 
         // Do not serialize filters if they are null.
         if (transformClosBytes == null && entryProcessorsCol != null)
-            transformClosBytes = CU.marshal(ctx, entryProcessorsCol);
+            transformClosBytes = CU.marshal(this.ctx, entryProcessorsCol);
 
         if (transferExpiry)
             transferExpiryPlc = expiryPlc != null && expiryPlc != this.ctx.expiry();
@@ -750,7 +750,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
 
         val.marshal(ctx, context());
 
-        expiryPlcBytes = transferExpiryPlc ?  CU.marshal(ctx, new IgniteExternalizableExpiryPolicy(expiryPlc)) : null;
+        expiryPlcBytes = transferExpiryPlc ?  CU.marshal(this.ctx, new IgniteExternalizableExpiryPolicy(expiryPlc)) : null;
     }
 
     /**
@@ -1038,4 +1038,4 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
         return GridToStringBuilder.toString(IgniteTxEntry.class, this, "xidVer", tx == null ? "null" : tx.xidVersion());
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
index c2cc629..530fbdf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
@@ -241,7 +241,8 @@ public class IgniteTxHandler {
                         req.version(),
                         null,
                         e,
-                        null);
+                        null,
+                        req.deployInfo() != null);
                 }
             }
         });
@@ -327,7 +328,8 @@ public class IgniteTxHandler {
                         req.version(),
                         null,
                         null,
-                        top.topologyVersion());
+                        top.topologyVersion(),
+                        req.deployInfo() != null);
 
                     try {
                         ctx.io().send(nearNode, res, req.policy());
@@ -787,7 +789,7 @@ public class IgniteTxHandler {
         GridDhtTxPrepareResponse res;
 
         try {
-            res = new GridDhtTxPrepareResponse(req.version(), req.futureId(), req.miniId());
+            res = new GridDhtTxPrepareResponse(req.version(), req.futureId(), req.miniId(), req.deployInfo() != null);
 
             // Start near transaction first.
             nearTx = !F.isEmpty(req.nearWrites()) ? startNearRemoteTx(ctx.deploy().globalLoader(), nodeId, req) : null;
@@ -833,7 +835,8 @@ public class IgniteTxHandler {
             if (nearTx != null)
                 nearTx.rollback();
 
-            res = new GridDhtTxPrepareResponse(req.version(), req.futureId(), req.miniId(), e);
+            res = new GridDhtTxPrepareResponse(req.version(), req.futureId(), req.miniId(), e,
+                req.deployInfo() != null);
         }
 
         try {
@@ -1344,7 +1347,8 @@ public class IgniteTxHandler {
         GridCacheTxRecoveryRequest req,
         boolean prepared) {
         GridCacheTxRecoveryResponse res =
-            new GridCacheTxRecoveryResponse(req.version(), req.futureId(), req.miniId(), prepared);
+            new GridCacheTxRecoveryResponse(req.version(), req.futureId(), req.miniId(), prepared,
+                req.deployInfo() != null);
 
         try {
             if (log.isDebugEnabled())
@@ -1382,4 +1386,4 @@ public class IgniteTxHandler {
 
         fut.onResult(nodeId, res);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 aa0ffe8..f22e753 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
@@ -164,6 +164,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     /** Implicit transaction result. */
     protected GridCacheReturn implicitRes;
 
+    /** Flag indicating whether deployment is enabled for caches from this transaction or not. */
+    private boolean depEnabled;
+
     /**
      * Empty constructor required for {@link Externalizable}.
      */
@@ -276,6 +279,11 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     }
 
     /** {@inheritDoc} */
+    @Override public boolean activeCachesDeploymentEnabled() {
+        return depEnabled;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean isStarted() {
         return txMap != null;
     }
@@ -3234,6 +3242,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
             }
             else
                 activeCacheIds.add(cacheId);
+
+            if (activeCacheIds.size() == 1)
+                depEnabled = cacheCtx.deploymentEnabled();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
index 6e7fadd..0bc102e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/IgniteCacheObjectProcessorImpl.java
@@ -91,7 +91,7 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
 
     /** {@inheritDoc} */
     @Override public byte[] marshal(CacheObjectContext ctx, Object val) throws IgniteCheckedException {
-        return CU.marshal(ctx.kernalContext().cache().context(), val);
+        return CU.marshal(ctx.kernalContext().cache().context(), ctx.addDeploymentInfo(), val);
     }
 
     /** {@inheritDoc} */
@@ -209,7 +209,8 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
         CacheObjectContext res = new CacheObjectContext(ctx,
             ccfg.getAffinityMapper() != null ? ccfg.getAffinityMapper() : new GridCacheDefaultAffinityKeyMapper(),
             ccfg.isCopyOnRead() && memMode != OFFHEAP_VALUES,
-            storeVal);
+            storeVal,
+            ctx.config().isPeerClassLoadingEnabled() && !isPortableEnabled(ccfg));
 
         ctx.resource().injectGeneric(res.defaultAffMapper());
 
@@ -392,4 +393,4 @@ public class IgniteCacheObjectProcessorImpl extends GridProcessorAdapter impleme
             return new CacheObjectByteArrayImpl(valCpy);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java
index 8c79a93..dd5bad0 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java
@@ -37,6 +37,16 @@ public abstract class AbstractMarshaller implements Marshaller {
     /** Context. */
     protected MarshallerContext ctx;
 
+
+    /**
+     * Undeployment callback invoked when class loader is being undeployed.
+     *
+     * Some marshallers may want to clean their internal state that uses the undeployed class loader somehow.
+     *
+     * @param ldr Class loader being undeployed.
+     */
+    public abstract void onUndeploy(ClassLoader ldr);
+
     /** {@inheritDoc} */
     @Override public void setContext(MarshallerContext ctx) {
         this.ctx = ctx;
@@ -71,4 +81,4 @@ public abstract class AbstractMarshaller implements Marshaller {
             U.close(in, null);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
index 0f4cf1f..deb3953 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
@@ -115,7 +115,12 @@ public class JdkMarshaller extends AbstractMarshaller {
     }
 
     /** {@inheritDoc} */
+    @Override public void onUndeploy(ClassLoader ldr) {
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(JdkMarshaller.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
index b9b782a..caccd99 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
@@ -288,7 +288,7 @@ public class OptimizedMarshaller extends AbstractMarshaller {
      *
      * @param ldr Class loader being undeployed.
      */
-    public void onUndeploy(ClassLoader ldr) {
+    @Override public void onUndeploy(ClassLoader ldr) {
         for (Class<?> cls : clsMap.keySet()) {
             if (ldr.equals(cls.getClassLoader()))
                 clsMap.remove(cls);
@@ -296,4 +296,4 @@ public class OptimizedMarshaller extends AbstractMarshaller {
 
         U.clearClassCache(ldr);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicEntryProcessorDeploymentSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicEntryProcessorDeploymentSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicEntryProcessorDeploymentSelfTest.java
new file mode 100644
index 0000000..0873d2d
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAtomicEntryProcessorDeploymentSelfTest.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import java.util.HashSet;
+import java.util.Map;
+import javax.cache.processor.EntryProcessorResult;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheEntryProcessor;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DeploymentMode;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+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 static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ * Cache EntryProcessor + Deployment.
+ */
+public class GridCacheAtomicEntryProcessorDeploymentSelfTest extends GridCommonAbstractTest {
+    /** IP finder. */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Entry processor */
+    protected static String TEST_ENT_PROCESSOR = "org.apache.ignite.tests.p2p.CacheDeploymentEntryProcessor";
+
+    /** Test value. */
+    protected static String TEST_VALUE = "org.apache.ignite.tests.p2p.CacheDeploymentTestValue";
+
+    /** */
+    private DeploymentMode depMode;
+
+    /** */
+    private boolean cliendMode;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        if (cliendMode)
+            cfg.setClientMode(cliendMode);
+
+        cfg.setDeploymentMode(depMode);
+
+        cfg.setCacheConfiguration(cacheConfiguration());
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(disco);
+
+        cfg.setConnectorConfiguration(null);
+
+        return cfg;
+    }
+
+    /**
+     * @return Cache configuration.
+     * @throws Exception In case of error.
+     */
+    protected CacheConfiguration cacheConfiguration() throws Exception {
+        CacheConfiguration cfg = defaultCacheConfiguration();
+
+        cfg.setCacheMode(PARTITIONED);
+        cfg.setWriteSynchronizationMode(FULL_SYNC);
+        cfg.setRebalanceMode(SYNC);
+        cfg.setAtomicityMode(atomicityMode());
+        cfg.setNearConfiguration(new NearCacheConfiguration());
+        cfg.setBackups(1);
+
+        return cfg;
+    }
+
+    protected CacheAtomicityMode atomicityMode() {
+        return ATOMIC;
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testInvokeDeployment() throws Exception {
+        depMode = DeploymentMode.CONTINUOUS;
+
+        doTestInvoke();
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testInvokeDeployment2() throws Exception {
+        depMode = DeploymentMode.SHARED;
+
+        doTestInvoke();
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testInvokeAllDeployment() throws Exception {
+        depMode = DeploymentMode.CONTINUOUS;
+
+        doTestInvokeAll();
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testInvokeAllDeployment2() throws Exception {
+        depMode = DeploymentMode.SHARED;
+
+        doTestInvokeAll();
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    private void doTestInvoke() throws Exception {
+        try {
+            cliendMode = false;
+            startGrid(0);
+
+            cliendMode = true;
+            startGrid(1);
+
+            ClassLoader ldr = getExternalClassLoader();
+
+            Class procCls = ldr.loadClass(TEST_ENT_PROCESSOR);
+            Class valCls = ldr.loadClass(TEST_VALUE);
+
+            assertTrue(grid(1).configuration().isClientMode());
+
+            IgniteCache cache = grid(1).cache(null);
+
+            cache.put("key", valCls.newInstance());
+
+            Boolean res = (Boolean)cache.invoke("key", (CacheEntryProcessor)procCls.newInstance());
+
+            assertTrue(res);
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    private void doTestInvokeAll() throws Exception {
+        try {
+            cliendMode = false;
+            startGrid(0);
+
+            cliendMode = true;
+            startGrid(1);
+
+            ClassLoader ldr = getExternalClassLoader();
+
+            Class procCls = ldr.loadClass(TEST_ENT_PROCESSOR);
+            Class valCls = ldr.loadClass(TEST_VALUE);
+
+            assertTrue(grid(1).configuration().isClientMode());
+
+            IgniteCache cache = grid(1).cache(null);
+
+            HashSet keys = new HashSet();
+
+            for (int i = 0; i < 3; i++) {
+                String key = "key" + i;
+
+                cache.put(key, valCls.newInstance());
+
+                keys.add(key);
+            }
+
+            Map<String, EntryProcessorResult> res = (Map<String, EntryProcessorResult>)cache.invokeAll(keys,
+                (CacheEntryProcessor)procCls.newInstance());
+
+            assertEquals(3, res.size());
+
+            for (EntryProcessorResult result : res.values())
+                assertTrue((Boolean)result.get());
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConditionalDeploymentSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConditionalDeploymentSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConditionalDeploymentSelfTest.java
new file mode 100644
index 0000000..c03eb08
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConditionalDeploymentSelfTest.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.managers.communication.GridIoMessageFactory;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.typedef.CO;
+import org.apache.ignite.plugin.extensions.communication.Message;
+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 static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ * Cache + conditional deployment test.
+ */
+public class GridCacheConditionalDeploymentSelfTest extends GridCommonAbstractTest {
+    /** IP finder. */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /**
+     *
+     */
+    static {
+        GridIoMessageFactory.registerCustom(TestMessage.DIRECT_TYPE, new CO<Message>() {
+            @Override public Message apply() {
+                return new TestMessage();
+            }
+        });
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setCacheConfiguration(cacheConfiguration());
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(disco);
+
+        return cfg;
+    }
+
+    /**
+     * @return Cache configuration.
+     * @throws Exception In case of error.
+     */
+    protected CacheConfiguration cacheConfiguration() throws Exception {
+        CacheConfiguration cfg = defaultCacheConfiguration();
+
+        cfg.setCacheMode(PARTITIONED);
+        cfg.setWriteSynchronizationMode(FULL_SYNC);
+        cfg.setRebalanceMode(SYNC);
+        cfg.setAtomicityMode(TRANSACTIONAL);
+        cfg.setBackups(1);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        Ignite ignite0 = startGrid(0);
+
+        startGrid(1);
+
+        ignite0.cache(null).put(1, new TestValue());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        Ignition.stopAll(true);
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testNoDeploymentInfo() throws Exception {
+        GridCacheIoManager ioMgr = cacheIoManager();
+
+        TestMessage msg = new TestMessage();
+
+        assertNull(msg.deployInfo());
+
+        msg.addDepInfo = false;
+
+        IgniteUtils.invoke(GridCacheIoManager.class, ioMgr, "onSend", msg, grid(1).cluster().localNode().id());
+
+        assertNull(msg.deployInfo());
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testAddedDeploymentInfo() throws Exception {
+        GridCacheIoManager ioMgr = cacheIoManager();
+
+        TestMessage msg = new TestMessage();
+
+        assertNull(msg.deployInfo());
+
+        msg.addDepInfo = true;
+
+        IgniteUtils.invoke(GridCacheIoManager.class, ioMgr, "onSend", msg, grid(1).cluster().localNode().id());
+
+        assertNotNull(msg.deployInfo());
+    }
+
+    /**
+     * @throws Exception In case of error.
+     */
+    public void testAddedDeploymentInfo2() throws Exception {
+        GridCacheContext ctx = cacheContext();
+
+        assertTrue(ctx.deploymentEnabled());
+
+        GridCacheIoManager ioMgr = cacheIoManager();
+
+        TestMessage msg = new TestMessage();
+
+        assertNull(msg.deployInfo());
+
+        msg.addDepInfo = false;
+
+        IgniteUtils.invoke(GridCacheIoManager.class, ioMgr, "onSend", msg, grid(1).cluster().localNode().id());
+
+        assertNull(msg.deployInfo());
+    }
+
+    protected GridCacheContext cacheContext() {
+        return ((IgniteCacheProxy)grid(0).cache(null)).context();
+    }
+
+    protected GridCacheIoManager cacheIoManager() {
+        return grid(0).context().cache().context().io();
+    }
+
+    /**
+     * Test message class.
+     */
+    public static class TestMessage  extends GridCacheMessage implements GridCacheDeployable {
+        /** */
+        public static final byte DIRECT_TYPE = (byte)302;
+
+        @Override public byte directType() {
+            return DIRECT_TYPE;
+        }
+
+        @Override public byte fieldsCount() {
+            return 3;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean addDeploymentInfo() {
+            return addDepInfo;
+        }
+    }
+
+    /** */
+    private static class TestValue {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentOffHeapSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentOffHeapSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentOffHeapSelfTest.java
index c51d72b..1adc3b4 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentOffHeapSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentOffHeapSelfTest.java
@@ -38,19 +38,4 @@ public class GridCacheDeploymentOffHeapSelfTest extends GridCacheDeploymentSelfT
 
         return cacheCfg;
     }
-
-    /** {@inheritDoc} */
-    @Override public void testDeployment() throws Exception {
-        fail("https://issues.apache.org/jira/browse/IGNITE-1618");
-    }
-
-    /** {@inheritDoc} */
-    @Override public void testDeployment6() throws Exception {
-        fail("https://issues.apache.org/jira/browse/IGNITE-1618");
-    }
-
-    /** {@inheritDoc} */
-    @Override public void testDeployment7() throws Exception {
-        fail("https://issues.apache.org/jira/browse/IGNITE-1618");
-    }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java
index 5965852..e18520d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java
@@ -48,28 +48,28 @@ public class GridCacheDeploymentSelfTest extends GridCommonAbstractTest {
     private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
 
     /** Name for grid without cache. */
-    private static final String GRID_NAME = "grid-no-cache";
+    protected static final String GRID_NAME = "grid-no-cache";
 
     /** First test task name. */
-    private static final String TEST_TASK_1 = "org.apache.ignite.tests.p2p.CacheDeploymentTestTask1";
+    protected static final String TEST_TASK_1 = "org.apache.ignite.tests.p2p.CacheDeploymentTestTask1";
 
     /** Second test task name. */
-    private static final String TEST_TASK_2 = "org.apache.ignite.tests.p2p.CacheDeploymentTestTask2";
+    protected static final String TEST_TASK_2 = "org.apache.ignite.tests.p2p.CacheDeploymentTestTask2";
 
     /** Third test task name. */
-    private static final String TEST_TASK_3 = "org.apache.ignite.tests.p2p.CacheDeploymentTestTask3";
+    protected static final String TEST_TASK_3 = "org.apache.ignite.tests.p2p.CacheDeploymentTestTask3";
 
     /** Test value 1. */
-    private static final String TEST_KEY = "org.apache.ignite.tests.p2p.CacheDeploymentTestKey";
+    protected static final String TEST_KEY = "org.apache.ignite.tests.p2p.CacheDeploymentTestKey";
 
     /** Test value 1. */
-    private static final String TEST_VALUE_1 = "org.apache.ignite.tests.p2p.CacheDeploymentTestValue";
+    protected static final String TEST_VALUE_1 = "org.apache.ignite.tests.p2p.CacheDeploymentTestValue";
 
     /** Test value 2. */
-    private static final String TEST_VALUE_2 = "org.apache.ignite.tests.p2p.CacheDeploymentTestValue2";
+    protected static final String TEST_VALUE_2 = "org.apache.ignite.tests.p2p.CacheDeploymentTestValue2";
 
     /** */
-    private DeploymentMode depMode;
+    protected DeploymentMode depMode;
 
     /** {@inheritDoc} */
     @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
@@ -249,11 +249,11 @@ public class GridCacheDeploymentSelfTest extends GridCommonAbstractTest {
 
             stopGrid(GRID_NAME);
 
-            assert g1.cache(null).localSize(CachePeekMode.ALL) == 1;
-            assert g1.cache(null).localSize(CachePeekMode.ALL) == 1;
+            assertEquals(1, g1.cache(null).localSize(CachePeekMode.ALL));
+            assertEquals(1, g1.cache(null).localSize(CachePeekMode.ALL));
 
-            assert g2.cache(null).localSize(CachePeekMode.ALL) == 1;
-            assert g2.cache(null).localSize(CachePeekMode.ALL) == 1;
+            assertEquals(1, g2.cache(null).localSize(CachePeekMode.ALL));
+            assertEquals(1, g2.cache(null).localSize(CachePeekMode.ALL));
 
             startGrid(3);
         }
@@ -436,4 +436,4 @@ public class GridCacheDeploymentSelfTest extends GridCommonAbstractTest {
         throw new IllegalStateException("Unable to find matching key [start=" + start + ", primary=" + primary.id() +
             ", backup=" + backup.id() + ']');
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTransactionalEntryProcessorDeploymentSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTransactionalEntryProcessorDeploymentSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTransactionalEntryProcessorDeploymentSelfTest.java
new file mode 100644
index 0000000..bf8cc7a
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTransactionalEntryProcessorDeploymentSelfTest.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import org.apache.ignite.cache.CacheAtomicityMode;
+
+/**
+ * Cache EntryProcessor + Deployment for transactional cache.
+ */
+public class GridCacheTransactionalEntryProcessorDeploymentSelfTest extends
+    GridCacheAtomicEntryProcessorDeploymentSelfTest {
+    /** {@inheritDoc} */
+    @Override protected CacheAtomicityMode atomicityMode() {
+        return CacheAtomicityMode.TRANSACTIONAL;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/spi/communication/GridCacheMessageSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/communication/GridCacheMessageSelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/communication/GridCacheMessageSelfTest.java
index 47dcdf1..9c97542 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/communication/GridCacheMessageSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/communication/GridCacheMessageSelfTest.java
@@ -215,6 +215,11 @@ public class GridCacheMessageSelfTest extends GridCommonAbstractTest {
             entries.add(entry);
         }
 
+        /** {@inheritDoc} */
+        @Override public boolean addDeploymentInfo() {
+            return false;
+        }
+
         /**
          * @return COllection of test messages.
          */
@@ -305,6 +310,11 @@ public class GridCacheMessageSelfTest extends GridCommonAbstractTest {
             this.body = body;
         }
 
+        /** {@inheritDoc} */
+        @Override public boolean addDeploymentInfo() {
+            return false;
+        }
+
         /**
          * @return Body.
          */
@@ -423,6 +433,11 @@ public class GridCacheMessageSelfTest extends GridCommonAbstractTest {
             this.body = body;
         }
 
+        /** {@inheritDoc} */
+        @Override public boolean addDeploymentInfo() {
+            return false;
+        }
+
         /**
          * @return Body.
          */
@@ -553,4 +568,4 @@ public class GridCacheMessageSelfTest extends GridCommonAbstractTest {
             return true;
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
index 0e5894d..7ee301c 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
@@ -76,7 +76,7 @@ public class IgniteBasicTestSuite extends TestSuite {
         suite.addTest(IgniteKernalSelfTestSuite.suite(ignoredTests));
         suite.addTest(IgniteStartUpTestSuite.suite());
         suite.addTest(IgniteExternalizableSelfTestSuite.suite());
-        suite.addTest(IgniteP2PSelfTestSuite.suite());
+        suite.addTest(IgniteP2PSelfTestSuite.suite(ignoredTests));
         suite.addTest(IgniteCacheP2pUnmarshallingErrorTestSuite.suite(ignoredTests));
         suite.addTest(IgniteStreamSelfTestSuite.suite());
 
@@ -116,4 +116,4 @@ public class IgniteBasicTestSuite extends TestSuite {
 
         return suite;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
index 1deb3bc..a4737c2 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
@@ -169,15 +169,15 @@ public class IgniteCacheTestSuite extends TestSuite {
         suite.addTestSuite(IgnitePutAllUpdateNonPreloadedPartitionSelfTest.class);
 
         // User's class loader tests.
-        suite.addTestSuite(IgniteCacheAtomicExecutionContextTest.class);
-        suite.addTestSuite(IgniteCachePartitionedExecutionContextTest.class);
-        suite.addTestSuite(IgniteCacheReplicatedExecutionContextTest.class);
-        suite.addTestSuite(IgniteCacheTxExecutionContextTest.class);
-        suite.addTestSuite(IgniteCacheContinuousExecutionContextTest.class);
-        suite.addTestSuite(IgniteCacheIsolatedExecutionContextTest.class);
-        suite.addTestSuite(IgniteCacheP2PDisableExecutionContextTest.class);
-        suite.addTestSuite(IgniteCachePrivateExecutionContextTest.class);
-        suite.addTestSuite(IgniteCacheSharedExecutionContextTest.class);
+        GridTestUtils.addTestIfNeeded(suite, IgniteCacheAtomicExecutionContextTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, IgniteCachePartitionedExecutionContextTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, IgniteCacheReplicatedExecutionContextTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, IgniteCacheTxExecutionContextTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, IgniteCacheContinuousExecutionContextTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, IgniteCacheIsolatedExecutionContextTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, IgniteCacheP2PDisableExecutionContextTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, IgniteCachePrivateExecutionContextTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, IgniteCacheSharedExecutionContextTest.class, ignoredTests);
 
         // Warmup closure tests.
         suite.addTestSuite(IgniteWarmupClosureSelfTest.class);

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
index 02a7f7f..796c531 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.testsuites;
 
 import junit.framework.TestSuite;
+import org.apache.ignite.internal.processors.cache.GridCacheAtomicEntryProcessorDeploymentSelfTest;
+import org.apache.ignite.internal.processors.cache.GridCacheConditionalDeploymentSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheDeploymentOffHeapSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheDeploymentSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryVersionSelfTest;
@@ -25,6 +27,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheOrderedPreloadingSel
 import org.apache.ignite.internal.processors.cache.GridCacheReferenceCleanupSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheReloadSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheReplicatedSynchronousCommitTest;
+import org.apache.ignite.internal.processors.cache.GridCacheTransactionalEntryProcessorDeploymentSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheValueBytesPreloadingSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheValueConsistencyTransactionalNearEnabledSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheValueConsistencyTransactionalSelfTest;
@@ -116,6 +119,9 @@ public class IgniteCacheTestSuite3 extends TestSuite {
 
         suite.addTestSuite(GridCacheDeploymentSelfTest.class);
         suite.addTestSuite(GridCacheDeploymentOffHeapSelfTest.class);
+        suite.addTestSuite(GridCacheConditionalDeploymentSelfTest.class);
+        suite.addTestSuite(GridCacheAtomicEntryProcessorDeploymentSelfTest.class);
+        suite.addTestSuite(GridCacheTransactionalEntryProcessorDeploymentSelfTest.class);
 
         suite.addTestSuite(GridCachePutArrayValueSelfTest.class);
         suite.addTestSuite(GridCacheReplicatedUnswapAdvancedSelfTest.class);
@@ -183,4 +189,4 @@ public class IgniteCacheTestSuite3 extends TestSuite {
 
         return suite;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
index ddf7d37..7bade98 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.testsuites;
 
+import java.util.Set;
 import junit.framework.TestSuite;
 import org.apache.ignite.internal.managers.deployment.GridDeploymentMessageCountSelfTest;
 import org.apache.ignite.p2p.GridP2PClassLoadingSelfTest;
@@ -33,17 +34,26 @@ import org.apache.ignite.p2p.GridP2PRemoteClassLoadersSelfTest;
 import org.apache.ignite.p2p.GridP2PSameClassLoaderSelfTest;
 import org.apache.ignite.p2p.GridP2PTimeoutSelfTest;
 import org.apache.ignite.p2p.GridP2PUndeploySelfTest;
+import org.apache.ignite.testframework.GridTestUtils;
 
 /**
  * P2P test suite.
  */
 public class IgniteP2PSelfTestSuite extends TestSuite {
     /**
+     * @return Suite.
+     * @throws Exception If failed.
+     */
+    public static TestSuite suite() throws Exception {
+        return suite(null);
+    }
+
+    /**
      * @return P2P tests suite.
      * @throws Exception If failed.
      */
     @SuppressWarnings({"ProhibitedExceptionDeclared"})
-    public static TestSuite suite() throws Exception {
+    public static TestSuite suite(Set<Class> ignoredTests) throws Exception {
         TestSuite suite = new TestSuite("Ignite P2P Test Suite");
 
         suite.addTest(new TestSuite(GridP2PDoubleDeploymentSelfTest.class));
@@ -60,8 +70,8 @@ public class IgniteP2PSelfTestSuite extends TestSuite {
         suite.addTest(new TestSuite(GridP2PTimeoutSelfTest.class));
         suite.addTest(new TestSuite(GridP2PMissedResourceCacheSizeSelfTest.class));
         suite.addTest(new TestSuite(GridP2PContinuousDeploymentSelfTest.class));
-        suite.addTest(new TestSuite(GridDeploymentMessageCountSelfTest.class));
+        GridTestUtils.addTestIfNeeded(suite, GridDeploymentMessageCountSelfTest.class, ignoredTests);
 
         return suite;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/CacheDeploymentEntryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/CacheDeploymentEntryProcessor.java b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/CacheDeploymentEntryProcessor.java
new file mode 100644
index 0000000..3d66fec
--- /dev/null
+++ b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/CacheDeploymentEntryProcessor.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.tests.p2p;
+
+import javax.cache.processor.EntryProcessorException;
+import javax.cache.processor.MutableEntry;
+import org.apache.ignite.cache.CacheEntryProcessor;
+
+/**
+ * Entry processor for {@code GridCacheEntryProcessorDeploymentSelfTest}.
+ */
+public class CacheDeploymentEntryProcessor implements CacheEntryProcessor<String, CacheDeploymentTestValue, Boolean> {
+    /** {@inheritDoc} */
+    @Override public Boolean process(MutableEntry<String, CacheDeploymentTestValue> entry,
+        Object... arguments) throws EntryProcessorException {
+        CacheDeploymentTestValue val = entry.getValue();
+
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/CacheDeploymentPortableEntryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/CacheDeploymentPortableEntryProcessor.java b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/CacheDeploymentPortableEntryProcessor.java
new file mode 100644
index 0000000..03d3efc
--- /dev/null
+++ b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/CacheDeploymentPortableEntryProcessor.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.tests.p2p;
+
+import javax.cache.processor.EntryProcessorException;
+import javax.cache.processor.MutableEntry;
+import org.apache.ignite.cache.CacheEntryProcessor;
+
+/**
+ * Entry processor used by {@code GridCacheEntryProcessorDeploymentSelfTest}.
+ */
+public class CacheDeploymentPortableEntryProcessor implements CacheEntryProcessor<String, String, Boolean> {
+    /** {@inheritDoc} */
+    @Override public Boolean process(MutableEntry<String, String> entry, Object... arguments)
+        throws EntryProcessorException {
+        String val = entry.getKey();
+
+        return true;
+    }
+}


[23/31] ignite git commit: ignite-1607 Implemented deadlock-free optimistic serializable tx mode

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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
new file mode 100644
index 0000000..70ddfa0
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
@@ -0,0 +1,4295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.cache.Cache;
+import javax.cache.CacheException;
+import javax.cache.configuration.Factory;
+import javax.cache.integration.CacheLoaderException;
+import javax.cache.processor.EntryProcessor;
+import javax.cache.processor.EntryProcessorResult;
+import javax.cache.processor.MutableEntry;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.store.CacheStore;
+import org.apache.ignite.cache.store.CacheStoreAdapter;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteClosure;
+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.spi.swapspace.inmemory.GridTestSwapSpaceSpi;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.apache.ignite.transactions.TransactionOptimisticException;
+import org.jsr166.ConcurrentHashMap8;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheMode.REPLICATED;
+import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.testframework.GridTestUtils.TestMemoryMode;
+import static org.apache.ignite.testframework.GridTestUtils.runMultiThreadedAsync;
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ *
+ */
+public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private static final boolean FAST = false;
+
+    /** */
+    private static Map<Integer, Integer> storeMap = new ConcurrentHashMap8<>();
+
+    /** */
+    private static final int SRVS = 4;
+
+    /** */
+    private static final int CLIENTS = 3;
+
+    /** */
+    private boolean client;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setPeerClassLoadingEnabled(false);
+
+        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER);
+
+        cfg.setClientMode(client);
+
+        cfg.setSwapSpaceSpi(new GridTestSwapSpaceSpi());
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        startGridsMultiThreaded(SRVS);
+
+        client = true;
+
+        startGridsMultiThreaded(SRVS, CLIENTS);
+
+        client = false;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        super.afterTestsStopped();
+
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long getTestTimeout() {
+        return 5 * 60_000;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxStreamerLoad() throws Exception {
+        txStreamerLoad(false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxStreamerLoadAllowOverwrite() throws Exception {
+        txStreamerLoad(true);
+    }
+
+    /**
+     * @param allowOverwrite Streamer flag.
+     * @throws Exception If failed.
+     */
+    private void txStreamerLoad(boolean allowOverwrite) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            if (ccfg.getCacheStoreFactory() == null)
+                continue;
+
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys)
+                    txStreamerLoad(ignite0, key, cache.getName(), allowOverwrite);
+
+                txStreamerLoad(ignite(SRVS), 10_000, cache.getName(), allowOverwrite);
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @param ignite Node.
+     * @param key Key.
+     * @param cacheName Cache name.
+     * @param allowOverwrite Streamer flag.
+     * @throws Exception If failed.
+     */
+    private void txStreamerLoad(Ignite ignite,
+        Integer key,
+        String cacheName,
+        boolean allowOverwrite) throws Exception {
+        IgniteCache<Integer, Integer> cache = ignite.cache(cacheName);
+
+        log.info("Test key: " + key);
+
+        Integer loadVal = -1;
+
+        IgniteTransactions txs = ignite.transactions();
+
+        try (IgniteDataStreamer<Integer, Integer> streamer = ignite.dataStreamer(cache.getName())) {
+            streamer.allowOverwrite(allowOverwrite);
+
+            streamer.addData(key, loadVal);
+        }
+
+        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+            Integer val = cache.get(key);
+
+            assertEquals(loadVal, val);
+
+            tx.commit();
+        }
+
+        checkValue(key, loadVal, cache.getName());
+
+        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+            Integer val = cache.get(key);
+
+            assertEquals(loadVal, val);
+
+            cache.put(key, 0);
+
+            tx.commit();
+        }
+
+        checkValue(key, 0, cache.getName());
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxLoadFromStore() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            if (ccfg.getCacheStoreFactory() == null)
+                continue;
+
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    Integer storeVal = -1;
+
+                    storeMap.put(key, storeVal);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Integer val = cache.get(key);
+
+                        assertEquals(storeVal, val);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, storeVal, cache.getName());
+
+                    cache.remove(key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Integer val = cache.get(key);
+
+                        assertNull(val);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxCommitReadOnly1() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Integer val = cache.get(key);
+
+                        assertNull(val);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Integer val = cache.get(key);
+
+                        assertNull(val);
+
+                        tx.rollback();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    cache.put(key, 1);
+
+                    cache.remove(key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Integer val = cache.get(key);
+
+                        assertNull(val);
+
+                        tx.commit();
+                    }
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxCommitReadOnly2() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (final Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Integer val = cache.get(key);
+
+                        assertNull(val);
+
+                        txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+                            new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+                                @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+                                    cache.get(key);
+
+                                    return null;
+                                }
+                            }
+                        );
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Integer val = cache.get(key);
+
+                        assertNull(val);
+
+                        txAsync(cache, PESSIMISTIC, REPEATABLE_READ,
+                            new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+                                @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+                                    cache.get(key);
+
+                                    return null;
+                                }
+                            }
+                        );
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxCommit() throws Exception {
+        Ignite ignite0 = ignite(0);
+        Ignite ignite1 = ignite(1);
+
+        final IgniteTransactions txs0 = ignite0.transactions();
+        final IgniteTransactions txs1 = ignite1.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache0 = ignite0.createCache(ccfg);
+                IgniteCache<Integer, Integer> cache1 = ignite1.cache(ccfg.getName());
+
+                List<Integer> keys = testKeys(cache0);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    Integer expVal = null;
+
+                    for (int i = 0; i < 100; i++) {
+                        try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = cache0.get(key);
+
+                            assertEquals(expVal, val);
+
+                            cache0.put(key, i);
+
+                            tx.commit();
+
+                            expVal = i;
+                        }
+
+                        try (Transaction tx = txs1.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = cache1.get(key);
+
+                            assertEquals(expVal, val);
+
+                            cache1.put(key, val);
+
+                            tx.commit();
+                        }
+
+                        try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = cache0.get(key);
+
+                            assertEquals(expVal, val);
+
+                            cache0.put(key, val);
+
+                            tx.commit();
+                        }
+                    }
+
+                    checkValue(key, expVal, cache0.getName());
+
+                    cache0.remove(key);
+
+                    try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Integer val = cache0.get(key);
+
+                        assertNull(val);
+
+                        cache0.put(key, expVal + 1);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, expVal + 1, cache0.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxRollback() throws Exception {
+        Ignite ignite0 = ignite(0);
+        Ignite ignite1 = ignite(1);
+
+        final IgniteTransactions txs0 = ignite0.transactions();
+        final IgniteTransactions txs1 = ignite1.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache0 = ignite0.createCache(ccfg);
+                IgniteCache<Integer, Integer> cache1 = ignite1.cache(ccfg.getName());
+
+                List<Integer> keys = testKeys(cache0);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    Integer expVal = null;
+
+                    for (int i = 0; i < 100; i++) {
+                        try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = cache0.get(key);
+
+                            assertEquals(expVal, val);
+
+                            cache0.put(key, i);
+
+                            tx.rollback();
+                        }
+
+                        try (Transaction tx = txs0.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = cache0.get(key);
+
+                            assertEquals(expVal, val);
+
+                            cache0.put(key, i);
+
+                            tx.commit();
+
+                            expVal = i;
+                        }
+
+                        try (Transaction tx = txs1.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = cache1.get(key);
+
+                            assertEquals(expVal, val);
+
+                            cache1.put(key, val);
+
+                            tx.commit();
+                        }
+                    }
+
+                    checkValue(key, expVal, cache0.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxCommitReadOnlyGetAll() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                Set<Integer> keys = new HashSet<>();
+
+                for (int i = 0; i < 100; i++)
+                    keys.add(i);
+
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    Map<Integer, Integer> map = cache.getAll(keys);
+
+                    assertTrue(map.isEmpty());
+
+                    tx.commit();
+                }
+
+                for (Integer key : keys)
+                    checkValue(key, null, cache.getName());
+
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    Map<Integer, Integer> map = cache.getAll(keys);
+
+                    assertTrue(map.isEmpty());
+
+                    tx.rollback();
+                }
+
+                for (Integer key : keys)
+                    checkValue(key, null, cache.getName());
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxCommitReadWriteTwoNodes() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                Integer key0 = primaryKey(ignite(0).cache(null));
+                Integer key1 = primaryKey(ignite(1).cache(null));
+
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    cache.put(key0, key0);
+
+                    cache.get(key1);
+
+                    tx.commit();
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictRead1() throws Exception {
+        txConflictRead(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictRead2() throws Exception {
+        txConflictRead(false);
+    }
+
+    /**
+     * @param noVal If {@code true} there is no cache value when read in tx.
+     * @throws Exception If failed.
+     */
+    private void txConflictRead(boolean noVal) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    Integer expVal = null;
+
+                    if (!noVal) {
+                        expVal = -1;
+
+                        cache.put(key, expVal);
+                    }
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = cache.get(key);
+
+                            assertEquals(expVal, val);
+
+                            updateKey(cache, key, 1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object val = cache.get(key);
+
+                        assertEquals(1, val);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 1, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictReadWrite1() throws Exception {
+        txConflictReadWrite(true, false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictReadWrite2() throws Exception {
+        txConflictReadWrite(false, false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictReadRemove1() throws Exception {
+        txConflictReadWrite(true, true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictReadRemove2() throws Exception {
+        txConflictReadWrite(false, true);
+    }
+
+    /**
+     * @param noVal If {@code true} there is no cache value when read in tx.
+     * @param rmv If {@code true} tests remove, otherwise put.
+     * @throws Exception If failed.
+     */
+    private void txConflictReadWrite(boolean noVal, boolean rmv) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    Integer expVal = null;
+
+                    if (!noVal) {
+                        expVal = -1;
+
+                        cache.put(key, expVal);
+                    }
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = cache.get(key);
+
+                            assertEquals(expVal, val);
+
+                            updateKey(cache, key, 1);
+
+                            if (rmv)
+                                cache.remove(key);
+                            else
+                                cache.put(key, 2);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Integer val = cache.get(key);
+
+                        assertEquals(1, (Object) val);
+
+                        if (rmv)
+                            cache.remove(key);
+                        else
+                            cache.put(key, 2);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, rmv ? null : 2, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed
+     */
+    public void testTxConflictGetAndPut1() throws Exception {
+        txConflictGetAndPut(true, false);
+    }
+
+    /**
+     * @throws Exception If failed
+     */
+    public void testTxConflictGetAndPut2() throws Exception {
+        txConflictGetAndPut(false, false);
+    }
+
+    /**
+     * @throws Exception If failed
+     */
+    public void testTxConflictGetAndRemove1() throws Exception {
+        txConflictGetAndPut(true, true);
+    }
+
+    /**
+     * @throws Exception If failed
+     */
+    public void testTxConflictGetAndRemove2() throws Exception {
+        txConflictGetAndPut(false, true);
+    }
+
+    /**
+     * @param noVal If {@code true} there is no cache value when read in tx.
+     * @param rmv If {@code true} tests remove, otherwise put.
+     * @throws Exception If failed.
+     */
+    private void txConflictGetAndPut(boolean noVal, boolean rmv) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    Integer expVal = null;
+
+                    if (!noVal) {
+                        expVal = -1;
+
+                        cache.put(key, expVal);
+                    }
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = rmv ? cache.getAndRemove(key) : cache.getAndPut(key, 2);
+
+                            assertEquals(expVal, val);
+
+                            updateKey(cache, key, 1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object val = rmv ? cache.getAndRemove(key) : cache.getAndPut(key, 2);
+
+                        assertEquals(1, val);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, rmv ? null : 2, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed
+     */
+    public void testTxConflictInvoke1() throws Exception {
+        txConflictInvoke(true, false);
+    }
+
+    /**
+     * @throws Exception If failed
+     */
+    public void testTxConflictInvoke2() throws Exception {
+        txConflictInvoke(false, false);
+    }
+
+    /**
+     * @throws Exception If failed
+     */
+    public void testTxConflictInvoke3() throws Exception {
+        txConflictInvoke(true, true);
+    }
+
+    /**
+     * @throws Exception If failed
+     */
+    public void testTxConflictInvoke4() throws Exception {
+        txConflictInvoke(false, true);
+    }
+
+    /**
+     * @param noVal If {@code true} there is no cache value when read in tx.
+     * @param rmv If {@code true} invoke does remove value, otherwise put.
+     * @throws Exception If failed.
+     */
+    private void txConflictInvoke(boolean noVal, boolean rmv) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    Integer expVal = null;
+
+                    if (!noVal) {
+                        expVal = -1;
+
+                        cache.put(key, expVal);
+                    }
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Integer val = cache.invoke(key, new SetValueProcessor(rmv ? null : 2));
+
+                            assertEquals(expVal, val);
+
+                            updateKey(cache, key, 1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object val = cache.invoke(key, new SetValueProcessor(rmv ? null : 2));
+
+                        assertEquals(1, val);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, rmv ? null : 2, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed
+     */
+    public void testTxConflictInvokeAll() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache0 = ignite0.createCache(ccfg);
+
+                final Integer key1 = primaryKey(ignite(0).cache(cache0.getName()));
+                final Integer key2 = primaryKey(ignite(1).cache(cache0.getName()));
+
+                Map<Integer, Integer> vals = new HashMap<>();
+
+                int newVal = 0;
+
+                for (Ignite ignite : G.allGrids()) {
+                    log.info("Test node: " + ignite.name());
+
+                    IgniteTransactions txs = ignite.transactions();
+
+                    IgniteCache<Integer, Integer> cache = ignite.cache(cache0.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Map<Integer, EntryProcessorResult<Integer>> res =
+                            cache.invokeAll(F.asSet(key1, key2), new SetValueProcessor(newVal));
+
+                        if (!vals.isEmpty()) {
+                            EntryProcessorResult<Integer> res1 = res.get(key1);
+
+                            assertNotNull(res1);
+                            assertEquals(vals.get(key1), res1.get());
+
+                            EntryProcessorResult<Integer> res2 = res.get(key2);
+
+                            assertNotNull(res2);
+                            assertEquals(vals.get(key2), res2.get());
+                        }
+                        else
+                            assertTrue(res.isEmpty());
+
+                        tx.commit();
+                    }
+
+                    checkValue(key1, newVal, cache.getName());
+                    checkValue(key2, newVal, cache.getName());
+
+                    vals.put(key1, newVal);
+                    vals.put(key2, newVal);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Map<Integer, EntryProcessorResult<Integer>> res =
+                                cache.invokeAll(F.asSet(key1, key2), new SetValueProcessor(newVal + 1));
+
+                            EntryProcessorResult<Integer> res1 = res.get(key1);
+
+                            assertNotNull(res1);
+                            assertEquals(vals.get(key1), res1.get());
+
+                            EntryProcessorResult<Integer> res2 = res.get(key2);
+
+                            assertNotNull(res2);
+                            assertEquals(vals.get(key2), res2.get());
+
+                            updateKey(cache0, key1, -1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key1, -1, cache.getName());
+                    checkValue(key2, newVal, cache.getName());
+
+                    vals.put(key1, -1);
+                    vals.put(key2, newVal);
+
+                    newVal++;
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictPutIfAbsent() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean put = cache.putIfAbsent(key, 2);
+
+                            assertTrue(put);
+
+                            updateKey(cache, key, 1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean put = cache.putIfAbsent(key, 2);
+
+                        assertFalse(put);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    cache.remove(key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean put = cache.putIfAbsent(key, 2);
+
+                        assertTrue(put);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 2, cache.getName());
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean put = cache.putIfAbsent(key, 2);
+
+                            assertFalse(put);
+
+                            updateKey(cache, key, 3);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 3, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictGetAndPutIfAbsent() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Object old = cache.getAndPutIfAbsent(key, 2);
+
+                            assertNull(old);
+
+                            updateKey(cache, key, 1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object old = cache.getAndPutIfAbsent(key, 2);
+
+                        assertEquals(1, old);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    cache.remove(key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object old = cache.getAndPutIfAbsent(key, 2);
+
+                        assertNull(old);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 2, cache.getName());
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Object old = cache.getAndPutIfAbsent(key, 4);
+
+                            assertEquals(2, old);
+
+                            updateKey(cache, key, 3);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 3, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictReplace() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (final Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean replace = cache.replace(key, 2);
+
+                            assertFalse(replace);
+
+                            updateKey(cache, key, 1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean replace = cache.replace(key, 2);
+
+                        assertTrue(replace);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 2, cache.getName());
+
+                    cache.remove(key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean replace = cache.replace(key, 2);
+
+                        assertFalse(replace);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean replace = cache.replace(key, 2);
+
+                            assertFalse(replace);
+
+                            updateKey(cache, key, 3);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 3, cache.getName());
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean replace = cache.replace(key, 2);
+
+                            assertTrue(replace);
+
+                            txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+                                new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+                                    @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+                                        cache.remove(key);
+
+                                        return null;
+                                    }
+                                }
+                            );
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    cache.put(key, 1);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean replace = cache.replace(key, 2);
+
+                        assertTrue(replace);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 2, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictGetAndReplace() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (final Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Object old = cache.getAndReplace(key, 2);
+
+                            assertNull(old);
+
+                            updateKey(cache, key, 1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object old = cache.getAndReplace(key, 2);
+
+                        assertEquals(1, old);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 2, cache.getName());
+
+                    cache.remove(key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object old = cache.getAndReplace(key, 2);
+
+                        assertNull(old);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Object old = cache.getAndReplace(key, 2);
+
+                            assertNull(old);
+
+                            updateKey(cache, key, 3);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 3, cache.getName());
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Object old = cache.getAndReplace(key, 2);
+
+                            assertEquals(3, old);
+
+                            txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+                                new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+                                    @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+                                        cache.remove(key);
+
+                                        return null;
+                                    }
+                                }
+                            );
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    cache.put(key, 1);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object old = cache.getAndReplace(key, 2);
+
+                        assertEquals(1, old);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 2, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictRemoveWithOldValue() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (final Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean rmv = cache.remove(key, 2);
+
+                            assertFalse(rmv);
+
+                            updateKey(cache, key, 1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean rmv = cache.remove(key, 1);
+
+                        assertTrue(rmv);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    cache.remove(key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean rmv = cache.remove(key, 2);
+
+                        assertFalse(rmv);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    cache.put(key, 2);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean rmv = cache.remove(key, 2);
+
+                            assertTrue(rmv);
+
+                            updateKey(cache, key, 3);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 3, cache.getName());
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean rmv = cache.remove(key, 3);
+
+                            assertTrue(rmv);
+
+                            txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+                                new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+                                    @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+                                        cache.remove(key);
+
+                                        return null;
+                                    }
+                                }
+                            );
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    cache.put(key, 1);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean rmv = cache.remove(key, 2);
+
+                        assertFalse(rmv);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean rmv = cache.remove(key, 1);
+
+                        assertTrue(rmv);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictCasReplace() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (final Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean replace = cache.replace(key, 1, 2);
+
+                            assertFalse(replace);
+
+                            updateKey(cache, key, 1);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean replace = cache.replace(key, 1, 2);
+
+                        assertTrue(replace);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 2, cache.getName());
+
+                    cache.remove(key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean replace = cache.replace(key, 1, 2);
+
+                        assertFalse(replace);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    cache.put(key, 2);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean replace = cache.replace(key, 2, 1);
+
+                            assertTrue(replace);
+
+                            updateKey(cache, key, 3);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, 3, cache.getName());
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            boolean replace = cache.replace(key, 3, 4);
+
+                            assertTrue(replace);
+
+                            txAsync(cache, OPTIMISTIC, SERIALIZABLE,
+                                new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+                                    @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+                                        cache.remove(key);
+
+                                        return null;
+                                    }
+                                }
+                            );
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    cache.put(key, 1);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean replace = cache.replace(key, 2, 3);
+
+                        assertFalse(replace);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean replace = cache.replace(key, 1, 3);
+
+                        assertTrue(replace);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 3, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictRemoveReturnBoolean1() throws Exception {
+        txConflictRemoveReturnBoolean(false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxConflictRemoveReturnBoolean2() throws Exception {
+        txConflictRemoveReturnBoolean(true);
+    }
+
+    /**
+     * @param noVal If {@code true} there is no cache value when do update in tx.
+     * @throws Exception If failed.
+     */
+    private void txConflictRemoveReturnBoolean(boolean noVal) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (final Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    if (!noVal)
+                        cache.put(key, -1);
+
+                    if (noVal) {
+                        try {
+                            try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                                boolean res = cache.remove(key);
+
+                                assertFalse(res);
+
+                                updateKey(cache, key, -1);
+
+                                tx.commit();
+                            }
+
+                            fail();
+                        }
+                        catch (TransactionOptimisticException e) {
+                            log.info("Expected exception: " + e);
+                        }
+
+                        checkValue(key, -1, cache.getName());
+                    }
+                    else {
+                        try {
+                            try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                                boolean res = cache.remove(key);
+
+                                assertTrue(res);
+
+                                txAsync(cache, PESSIMISTIC, REPEATABLE_READ,
+                                    new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+                                        @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+                                            cache.remove(key);
+
+                                            return null;
+                                        }
+                                    }
+                                );
+
+                                tx.commit();
+                            }
+
+                            fail();
+                        }
+                        catch (TransactionOptimisticException e) {
+                            log.info("Expected exception: " + e);
+                        }
+
+                        checkValue(key, null, cache.getName());
+
+                        cache.put(key, -1);
+                    }
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean res = cache.remove(key);
+
+                        assertTrue(res);
+
+                        updateKey(cache, key, 2);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    // Check no conflict for removeAll with single key.
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache.removeAll(Collections.singleton(key));
+
+                        txAsync(cache, PESSIMISTIC, REPEATABLE_READ,
+                            new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+                                @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+                                    cache.remove(key);
+
+                                    return null;
+                                }
+                            }
+                        );
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    cache.put(key, 2);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean res = cache.remove(key);
+
+                        assertTrue(res);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean res = cache.remove(key);
+
+                        assertFalse(res);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, null, cache.getName());
+
+                    try {
+                        cache.put(key, 1);
+
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            Object val = cache.get(key);
+
+                            assertEquals(1, val);
+
+                            boolean res = cache.remove(key);
+
+                            assertTrue(res);
+
+                            updateKey(cache, key, 2);
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxNoConflictPut1() throws Exception {
+        txNoConflictUpdate(true, false, false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxNoConflictPut2() throws Exception {
+        txNoConflictUpdate(false, false, false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxNoConflictPut3() throws Exception {
+        txNoConflictUpdate(false, false, true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxNoConflictRemove1() throws Exception {
+        txNoConflictUpdate(true, true, false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxNoConflictRemove2() throws Exception {
+        txNoConflictUpdate(false, true, false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxNoConflictRemove3() throws Exception {
+        txNoConflictUpdate(false, true, true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     * @param noVal If {@code true} there is no cache value when do update in tx.
+     * @param rmv If {@code true} tests remove, otherwise put.
+     * @param getAfterUpdate If {@code true} tries to get value in tx after update.
+     */
+    private void txNoConflictUpdate(boolean noVal, boolean rmv, boolean getAfterUpdate) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    if (!noVal)
+                        cache.put(key, -1);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        if (rmv)
+                            cache.remove(key);
+                        else
+                            cache.put(key, 2);
+
+                        if (getAfterUpdate) {
+                            Object val = cache.get(key);
+
+                            if (rmv)
+                                assertNull(val);
+                            else
+                                assertEquals(2, val);
+                        }
+
+                        if (!rmv)
+                            updateKey(cache, key, 1);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, rmv ? null : 2, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache.put(key, 3);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 3, cache.getName());
+                }
+
+                Map<Integer, Integer> map = new HashMap<>();
+
+                for (int i = 0; i < 100; i++)
+                    map.put(i, i);
+
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    if (rmv)
+                        cache.removeAll(map.keySet());
+                    else
+                        cache.putAll(map);
+
+                    if (getAfterUpdate) {
+                        Map<Integer, Integer> res = cache.getAll(map.keySet());
+
+                        if (rmv) {
+                            for (Integer key : map.keySet())
+                                assertNull(res.get(key));
+                        }
+                        else {
+                            for (Integer key : map.keySet())
+                                assertEquals(map.get(key), res.get(key));
+                        }
+                    }
+
+                    txAsync(cache, PESSIMISTIC, REPEATABLE_READ,
+                        new IgniteClosure<IgniteCache<Integer, Integer>, Void>() {
+                            @Override public Void apply(IgniteCache<Integer, Integer> cache) {
+                                Map<Integer, Integer> map = new HashMap<>();
+
+                                for (int i = 0; i < 100; i++)
+                                    map.put(i, -1);
+
+                                cache.putAll(map);
+
+                                return null;
+                            }
+                        }
+                    );
+
+                    tx.commit();
+                }
+
+                for (int i = 0; i < 100; i++)
+                    checkValue(i, rmv ? null : i, cache.getName());
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxNoConflictContainsKey1() throws Exception {
+        txNoConflictContainsKey(false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxNoConflictContainsKey2() throws Exception {
+        txNoConflictContainsKey(true);
+    }
+
+    /**
+     * @param noVal If {@code true} there is no cache value when do update in tx.
+     * @throws Exception If failed.
+     */
+    private void txNoConflictContainsKey(boolean noVal) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    if (!noVal)
+                        cache.put(key, -1);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean res = cache.containsKey(key);
+
+                        assertEquals(!noVal, res);
+
+                        updateKey(cache, key, 1);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean res = cache.containsKey(key);
+
+                        assertTrue(res);
+
+                        updateKey(cache, key, 2);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 2, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean res = cache.containsKey(key);
+
+                        assertTrue(res);
+
+                        tx.commit();
+                    }
+
+                    cache.remove(key);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        boolean res = cache.containsKey(key);
+
+                        assertFalse(res);
+
+                        updateKey(cache, key, 3);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 3, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxRollbackIfLocked1() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                List<Integer> keys = testKeys(cache);
+
+                for (Integer key : keys) {
+                    log.info("Test key: " + key);
+
+                    CountDownLatch latch = new CountDownLatch(1);
+
+                    IgniteInternalFuture<?> fut = lockKey(latch, cache, key);
+
+                    try {
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            cache.put(key, 2);
+
+                            log.info("Commit");
+
+                            tx.commit();
+                        }
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
+                    }
+
+                    latch.countDown();
+
+                    fut.get();
+
+                    checkValue(key, 1, cache.getName());
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache.put(key, 2);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, 2, cache.getName());
+                }
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxRollbackIfLocked2() throws Exception {
+        rollbackIfLockedPartialLock(false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxRollbackIfLocked3() throws Exception {
+        rollbackIfLockedPartialLock(true);
+    }
+
+    /**
+     * @param locKey If {@code true} gets lock for local key.
+     * @throws Exception If failed.
+     */
+    private void rollbackIfLockedPartialLock(boolean locKey) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final IgniteTransactions txs = ignite0.transactions();
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            logCacheInfo(ccfg);
+
+            try {
+                IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
+
+                final Integer key1 = primaryKey(ignite(1).cache(cache.getName()));
+                final Integer key2 = locKey ? primaryKey(cache) : primaryKey(ignite(2).cache(cache.getName()));
+
+                CountDownLatch latch = new CountDownLatch(1);
+
+                IgniteInternalFuture<?> fut = lockKey(latch, cache, key1);
+
+                try {
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache.put(key1, 2);
+                        cache.put(key2, 2);
+
+                        tx.commit();
+                    }
+
+                    fail();
+                }
+                catch (TransactionOptimisticException e) {
+                    log.info("Expected exception: " + e);
+                }
+
+                latch.countDown();
+
+                fut.get();
+
+                checkValue(key1, 1, cache.getName());
+                checkValue(key2, null, cache.getName());
+
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    cache.put(key1, 2);
+                    cache.put(key2, 2);
+
+                    tx.commit();
+                }
+
+                checkValue(key1, 2, cache.getName());
+                checkValue(key2, 2, cache.getName());
+            }
+            finally {
+                destroyCache(ignite0, ccfg.getName());
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNearCacheReaderUpdate() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        IgniteCache<Integer, Integer> cache0 =
+            ignite0.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false));
+
+        final String cacheName = cache0.getName();
+
+        try {
+            Ignite client1 = ignite(SRVS);
+            Ignite client2 = ignite(SRVS + 1);
+
+            IgniteCache<Integer, Integer> cache1 = client1.createNearCache(cacheName,
+                new NearCacheConfiguration<Integer, Integer>());
+            IgniteCache<Integer, Integer> cache2 = client2.createNearCache(cacheName,
+                new NearCacheConfiguration<Integer, Integer>());
+
+            Integer key = primaryKey(ignite(0).cache(cacheName));
+
+            try (Transaction tx = client1.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+                assertNull(cache1.get(key));
+                cache1.put(key, 1);
+
+                tx.commit();
+            }
+
+            try (Transaction tx = client2.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+                assertEquals(1, (Object) cache2.get(key));
+                cache2.put(key, 2);
+
+                tx.commit();
+            }
+
+            try (Transaction tx = client1.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+                assertEquals(2, (Object)cache1.get(key));
+                cache1.put(key, 3);
+
+                tx.commit();
+            }
+        }
+        finally {
+            ignite0.destroyCache(cacheName);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRollbackNearCache1() throws Exception {
+        rollbackNearCacheWrite(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRollbackNearCache2() throws Exception {
+        rollbackNearCacheWrite(false);
+    }
+
+    /**
+     * @param near If {@code true} locks entry using the same near cache.
+     * @throws Exception If failed.
+     */
+    private void rollbackNearCacheWrite(boolean near) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        IgniteCache<Integer, Integer> cache0 =
+            ignite0.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false));
+
+        final String cacheName = cache0.getName();
+
+        try {
+            Ignite ignite = ignite(SRVS);
+
+            IgniteCache<Integer, Integer> cache = ignite.createNearCache(cacheName,
+                new NearCacheConfiguration<Integer, Integer>());
+
+            IgniteTransactions txs = ignite.transactions();
+
+            Integer key1 = primaryKey(ignite(0).cache(cacheName));
+            Integer key2 = primaryKey(ignite(1).cache(cacheName));
+            Integer key3 = primaryKey(ignite(2).cache(cacheName));
+
+            CountDownLatch latch = new CountDownLatch(1);
+
+            IgniteInternalFuture<?> fut = null;
+
+            try {
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    cache.put(key1, key1);
+                    cache.put(key2, key2);
+                    cache.put(key3, key3);
+
+                    fut = lockKey(latch, near ? cache : cache0, key2);
+
+                    tx.commit();
+                }
+
+                fail();
+            }
+            catch (TransactionOptimisticException e) {
+                log.info("Expected exception: " + e);
+            }
+
+            latch.countDown();
+
+            assert fut != null;
+
+            fut.get();
+
+            checkValue(key1, null, cacheName);
+            checkValue(key2, 1, cacheName);
+            checkValue(key3, null, cacheName);
+
+            try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                cache.put(key1, key1);
+                cache.put(key2, key2);
+                cache.put(key3, key3);
+
+                tx.commit();
+            }
+
+            checkValue(key1, key1, cacheName);
+            checkValue(key2, key2, cacheName);
+            checkValue(key3, key3, cacheName);
+        }
+        finally {
+            ignite0.destroyCache(cacheName);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRollbackNearCache3() throws Exception {
+        rollbackNearCacheRead(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRollbackNearCache4() throws Exception {
+        rollbackNearCacheRead(false);
+    }
+
+    /**
+     * @param near If {@code true} updates entry using the same near cache.
+     * @throws Exception If failed.
+     */
+    private void rollbackNearCacheRead(boolean near) throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        IgniteCache<Integer, Integer> cache0 =
+            ignite0.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false));
+
+        final String cacheName = cache0.getName();
+
+        try {
+            Ignite ignite = ignite(SRVS);
+
+            IgniteCache<Integer, Integer> cache = ignite.createNearCache(cacheName,
+                new NearCacheConfiguration<Integer, Integer>());
+
+            IgniteTransactions txs = ignite.transactions();
+
+            Integer key1 = primaryKey(ignite(0).cache(cacheName));
+            Integer key2 = primaryKey(ignite(1).cache(cacheName));
+            Integer key3 = primaryKey(ignite(2).cache(cacheName));
+
+            cache0.put(key1, -1);
+            cache0.put(key2, -1);
+            cache0.put(key3, -1);
+
+            try {
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    cache.get(key1);
+                    cache.get(key2);
+                    cache.get(key3);
+
+                    updateKey(near ? cache : cache0, key2, -2);
+
+                    tx.commit();
+                }
+
+                fail();
+            }
+            catch (TransactionOptimisticException e) {
+                log.info("Expected exception: " + e);
+            }
+
+            checkValue(key1, -1, cacheName);
+            checkValue(key2, -2, cacheName);
+            checkValue(key3, -1, cacheName);
+
+            try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                cache.put(key1, key1);
+                cache.put(key2, key2);
+                cache.put(key3, key3);
+
+                tx.commit();
+            }
+
+            checkValue(key1, key1, cacheName);
+            checkValue(key2, key2, cacheName);
+            checkValue(key3, key3, cacheName);
+        }
+        finally {
+            ignite0.destroyCache(cacheName);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testCrossCacheTx() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        final String CACHE1 = "cache1";
+        final String CACHE2 = "cache2";
+
+        try {
+            CacheConfiguration<Integer, Integer> ccfg1 =
+                cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
+
+            ccfg1.setName(CACHE1);
+
+            ignite0.createCache(ccfg1);
+
+            CacheConfiguration<Integer, Integer> ccfg2=
+                cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
+
+            ccfg2.setName(CACHE2);
+
+            ignite0.createCache(ccfg2);
+
+            Integer newVal = 0;
+
+            List<Integer> keys = testKeys(ignite0.<Integer, Integer>cache(CACHE1));
+
+            for (Ignite ignite : G.allGrids()) {
+                log.info("Test node: " + ignite.name());
+
+                IgniteCache<Integer, Integer> cache1 = ignite.cache(CACHE1);
+                IgniteCache<Integer, Integer> cache2 = ignite.cache(CACHE2);
+
+                IgniteTransactions txs = ignite.transactions();
+
+                for (Integer key : keys) {
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache1.put(key, newVal);
+                        cache2.put(key, newVal);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, newVal, CACHE1);
+                    checkValue(key, newVal, CACHE2);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object val1 = cache1.get(key);
+                        Object val2 = cache2.get(key);
+
+                        assertEquals(newVal, val1);
+                        assertEquals(newVal, val2);
+
+                        tx.commit();
+                    }
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache1.put(key, newVal + 1);
+                        cache2.put(key, newVal + 1);
+
+                        tx.rollback();
+                    }
+
+                    checkValue(key, newVal, CACHE1);
+                    checkValue(key, newVal, CACHE2);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object val1 = cache1.get(key);
+                        Object val2 = cache2.get(key);
+
+                        assertEquals(newVal, val1);
+                        assertEquals(newVal, val2);
+
+                        cache1.put(key, newVal + 1);
+                        cache2.put(key, newVal + 1);
+
+                        tx.commit();
+                    }
+
+                    newVal++;
+
+                    checkValue(key, newVal, CACHE1);
+                    checkValue(key, newVal, CACHE2);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache1.put(key, newVal);
+                        cache2.put(-key, newVal);
+
+                        tx.commit();
+                    }
+
+                    checkValue(key, newVal, CACHE1);
+                    checkValue(-key, null, CACHE1);
+
+                    checkValue(key, newVal, CACHE2);
+                    checkValue(-key, newVal, CACHE2);
+                }
+
+                newVal++;
+
+                Integer key1 = primaryKey(ignite(0).cache(CACHE1));
+                Integer key2 = primaryKey(ignite(1).cache(CACHE1));
+
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    cache1.put(key1, newVal);
+                    cache1.put(key2, newVal);
+
+                    cache2.put(key1, newVal);
+                    cache2.put(key2, newVal);
+
+                    tx.commit();
+                }
+
+                checkValue(key1, newVal, CACHE1);
+                checkValue(key2, newVal, CACHE1);
+                checkValue(key1, newVal, CACHE2);
+                checkValue(key2, newVal, CACHE2);
+
+                CountDownLatch latch = new CountDownLatch(1);
+
+                IgniteInternalFuture<?> fut = lockKey(latch, cache1, key1);
+
+                try {
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache1.put(key1, newVal + 1);
+                        cache2.put(key1, newVal + 1);
+
+                        tx.commit();
+                    }
+
+                    fail();
+                }
+                catch (TransactionOptimisticException e) {
+                    log.info("Expected exception: " + e);
+                }
+
+                latch.countDown();
+
+                fut.get();
+
+                checkValue(key1, 1, CACHE1);
+                checkValue(key1, newVal, CACHE2);
+
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    cache1.put(key1, newVal + 1);
+                    cache2.put(key1, newVal + 1);
+
+                    tx.commit();
+                }
+
+                newVal++;
+
+                cache1.put(key2, newVal);
+                cache2.put(key2, newVal);
+
+                checkValue(key1, newVal, CACHE1);
+                checkValue(key1, newVal, CACHE2);
+
+                latch = new CountDownLatch(1);
+
+                fut = lockKey(latch, cache1, key1);
+
+                try {
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache1.put(key1, newVal + 1);
+                        cache2.put(key2, newVal + 1);
+
+                        tx.commit();
+                    }
+
+                    fail();
+                }
+                catch (TransactionOptimisticException e) {
+                    log.info("Expected exception: " + e);
+                }
+
+                latch.countDown();
+
+                fut.get();
+
+                checkValue(key1, 1, CACHE1);
+                checkValue(key2, newVal, CACHE2);
+
+                try {
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object val1 = cache1.get(key1);
+       

<TRUNCATED>

[10/31] ignite git commit: ignite-1272: support of custom class loaders and conditional deployment info for portable marshaller and portable caches

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 1a869e7..c09a611 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
@@ -408,7 +408,8 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
         boolean cancelled = false;
 
         try {
-            res = new GridDhtLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), cnt);
+            res = new GridDhtLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(), cnt,
+                ctx.deploymentEnabled());
 
             dhtTx = startRemoteTx(nodeId, req, res);
             nearTx = isNearEnabled(cacheCfg) ? near().startRemoteTx(nodeId, req) : null;
@@ -435,7 +436,7 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
             U.error(log, err, e);
 
             res = new GridDhtLockResponse(ctx.cacheId(), req.version(), req.futureId(), req.miniId(),
-                new IgniteTxRollbackCheckedException(err, e));
+                new IgniteTxRollbackCheckedException(err, e), ctx.deploymentEnabled());
 
             fail = true;
         }
@@ -448,7 +449,7 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
                 req.version(),
                 req.futureId(),
                 req.miniId(),
-                new IgniteCheckedException(err, e));
+                new IgniteCheckedException(err, e), ctx.deploymentEnabled());
 
             fail = true;
         }
@@ -1035,7 +1036,8 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
             false,
             0,
             null,
-            topVer);
+            topVer,
+            ctx.deploymentEnabled());
 
         try {
             ctx.io().send(nearNode, res, ctx.ioPolicy());
@@ -1080,7 +1082,8 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
                 tx != null && tx.onePhaseCommit(),
                 entries.size(),
                 err,
-                null);
+                null,
+                ctx.deploymentEnabled());
 
             if (err == null) {
                 res.pending(localDhtPendingVersions(entries, mappedVer));
@@ -1196,7 +1199,8 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
                 false,
                 entries.size(),
                 e,
-                null);
+                null,
+                ctx.deploymentEnabled());
         }
     }
 
@@ -1522,7 +1526,8 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
 
             List<KeyCacheObject> keyBytes = entry.getValue();
 
-            GridDhtUnlockRequest req = new GridDhtUnlockRequest(ctx.cacheId(), keyBytes.size());
+            GridDhtUnlockRequest req = new GridDhtUnlockRequest(ctx.cacheId(), keyBytes.size(),
+                ctx.deploymentEnabled());
 
             req.version(dhtVer);
 
@@ -1556,7 +1561,8 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
             if (!dhtMap.containsKey(n)) {
                 List<KeyCacheObject> keyBytes = entry.getValue();
 
-                GridDhtUnlockRequest req = new GridDhtUnlockRequest(ctx.cacheId(), keyBytes.size());
+                GridDhtUnlockRequest req = new GridDhtUnlockRequest(ctx.cacheId(), keyBytes.size(),
+                    ctx.deploymentEnabled());
 
                 req.version(dhtVer);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
index 79bccc2..992bd66 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
@@ -320,7 +320,8 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCompoundIdentityFutur
                 tx.pendingVersions(),
                 tx.size(),
                 tx.subjectId(),
-                tx.taskNameHash());
+                tx.taskNameHash(),
+                tx.activeCachesDeploymentEnabled());
 
             try {
                 cctx.io().send(n, req, tx.ioPolicy());
@@ -397,7 +398,8 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCompoundIdentityFutur
                 tx.pendingVersions(),
                 tx.size(),
                 tx.subjectId(),
-                tx.taskNameHash());
+                tx.taskNameHash(),
+                tx.activeCachesDeploymentEnabled());
 
             req.writeVersion(tx.writeVersion() != null ? tx.writeVersion() : tx.xidVersion());
 
@@ -450,7 +452,8 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCompoundIdentityFutur
                     tx.pendingVersions(),
                     tx.size(),
                     tx.subjectId(),
-                    tx.taskNameHash());
+                    tx.taskNameHash(),
+                    tx.activeCachesDeploymentEnabled());
 
                 req.writeVersion(tx.writeVersion());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
index be59a95..caa0aa5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishRequest.java
@@ -104,6 +104,7 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
      * @param txSize Expected transaction size.
      * @param subjId Subject ID.
      * @param taskNameHash Task name hash.
+     * @param addDepInfo Deployment info flag.
      */
     public GridDhtTxFinishRequest(
         UUID nearNodeId,
@@ -127,7 +128,8 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
         Collection<GridCacheVersion> pendingVers,
         int txSize,
         @Nullable UUID subjId,
-        int taskNameHash
+        int taskNameHash,
+        boolean addDepInfo
     ) {
         super(
             xidVer,
@@ -143,7 +145,8 @@ public class GridDhtTxFinishRequest extends GridDistributedTxFinishRequest {
             baseVer,
             committedVers,
             rolledbackVers,
-            txSize);
+            txSize,
+            addDepInfo);
 
         assert miniId != null;
         assert nearNodeId != null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java
index ec0f234..fb4d97d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishResponse.java
@@ -214,4 +214,4 @@ public class GridDhtTxFinishResponse extends GridDistributedTxFinishResponse {
     @Override public byte fieldsCount() {
         return 8;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 761bbb0..a15a334 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
@@ -670,7 +670,8 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
             tx.writeVersion(),
             ret,
             prepErr,
-            null);
+            null,
+            tx.activeCachesDeploymentEnabled());
 
         if (prepErr == null) {
             addDhtValues(res);
@@ -976,7 +977,8 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
                         true,
                         tx.onePhaseCommit(),
                         tx.subjectId(),
-                        tx.taskNameHash());
+                        tx.taskNameHash(),
+                        tx.activeCachesDeploymentEnabled());
 
                     int idx = 0;
 
@@ -1075,7 +1077,8 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
                             true,
                             tx.onePhaseCommit(),
                             tx.subjectId(),
-                            tx.taskNameHash());
+                            tx.taskNameHash(),
+                            tx.activeCachesDeploymentEnabled());
 
                         for (IgniteTxEntry entry : nearMapping.writes()) {
                             try {

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java
index 29d5a70..fcd66c2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java
@@ -29,6 +29,7 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.GridDirectCollection;
 import org.apache.ignite.internal.GridDirectTransient;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxPrepareRequest;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
@@ -116,7 +117,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
      * @param txNodes Transaction nodes mapping.
      * @param nearXidVer Near transaction ID.
      * @param last {@code True} if this is last prepare request for node.
-     * @param onePhaseCommit One phase commit flag.
+     * @param addDepInfo Deployment info flag.
      */
     public GridDhtTxPrepareRequest(
         IgniteUuid futId,
@@ -130,8 +131,9 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
         boolean last,
         boolean onePhaseCommit,
         UUID subjId,
-        int taskNameHash) {
-        super(tx, null, dhtWrites, txNodes, onePhaseCommit);
+        int taskNameHash,
+        boolean addDepInfo) {
+        super(tx, null, dhtWrites, txNodes, onePhaseCommit, addDepInfo);
 
         assert futId != null;
         assert miniId != null;
@@ -271,8 +273,11 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
         return owned;
     }
 
-    /** {@inheritDoc}
-     * @param ctx*/
+    /**
+     * {@inheritDoc}
+     *
+     * @param ctx
+     */
     @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
         super.prepareMarshal(ctx);
 
@@ -281,12 +286,13 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
 
             ownedVals = owned.values();
 
-            for (IgniteTxKey key: ownedKeys)
-                key.prepareMarshal(ctx.cacheContext(key.cacheId()));
+            for (IgniteTxKey key: ownedKeys) {
+                GridCacheContext cctx = ctx.cacheContext(key.cacheId());
+
+                key.prepareMarshal(cctx);
 
-            if (ctx.deploymentEnabled()) {
-                for (IgniteTxKey k : owned.keySet())
-                    prepareObject(k, ctx);
+                if (addDepInfo)
+                    prepareObject(key, cctx);
             }
         }
 
@@ -551,4 +557,4 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
     @Override public byte fieldsCount() {
         return 35;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java
index d903165..2eba9f1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareResponse.java
@@ -84,9 +84,10 @@ public class GridDhtTxPrepareResponse extends GridDistributedTxPrepareResponse {
      * @param xid Xid version.
      * @param futId Future ID.
      * @param miniId Mini future ID.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridDhtTxPrepareResponse(GridCacheVersion xid, IgniteUuid futId, IgniteUuid miniId) {
-        super(xid);
+    public GridDhtTxPrepareResponse(GridCacheVersion xid, IgniteUuid futId, IgniteUuid miniId, boolean addDepInfo) {
+        super(xid, addDepInfo);
 
         assert futId != null;
         assert miniId != null;
@@ -100,9 +101,11 @@ public class GridDhtTxPrepareResponse extends GridDistributedTxPrepareResponse {
      * @param futId Future ID.
      * @param miniId Mini future ID.
      * @param err Error.
+     * @param addDepInfo Deployment enabled.
      */
-    public GridDhtTxPrepareResponse(GridCacheVersion xid, IgniteUuid futId, IgniteUuid miniId, Throwable err) {
-        super(xid, err);
+    public GridDhtTxPrepareResponse(GridCacheVersion xid, IgniteUuid futId, IgniteUuid miniId, Throwable err,
+        boolean addDepInfo) {
+        super(xid, err, addDepInfo);
 
         assert futId != null;
         assert miniId != null;
@@ -367,4 +370,4 @@ public class GridDhtTxPrepareResponse extends GridDistributedTxPrepareResponse {
     @Override public byte fieldsCount() {
         return 14;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtUnlockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtUnlockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtUnlockRequest.java
index e18dc33..38152a7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtUnlockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtUnlockRequest.java
@@ -52,9 +52,10 @@ public class GridDhtUnlockRequest extends GridDistributedUnlockRequest {
     /**
      * @param cacheId Cache ID.
      * @param dhtCnt Key count.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridDhtUnlockRequest(int cacheId, int dhtCnt) {
-        super(cacheId, dhtCnt);
+    public GridDhtUnlockRequest(int cacheId, int dhtCnt, boolean addDepInfo) {
+        super(cacheId, dhtCnt, addDepInfo);
     }
 
     /**
@@ -157,4 +158,4 @@ public class GridDhtUnlockRequest extends GridDistributedUnlockRequest {
     @Override public byte fieldsCount() {
         return 9;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
index abbe7b8..a68e834 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
@@ -409,7 +409,8 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
                     subjId,
                     taskName == null ? 0 : taskName.hashCode(),
                     expiryPlc != null ? expiryPlc.forAccess() : -1L,
-                    skipVals);
+                    skipVals,
+                    cctx.deploymentEnabled());
 
                 add(fut); // Append new future.
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 854a83d..cba6872 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
@@ -1087,9 +1087,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
         GridNearAtomicUpdateRequest req,
         CI2<GridNearAtomicUpdateRequest, GridNearAtomicUpdateResponse> completionCb
     ) {
-        GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(ctx.cacheId(),
-            nodeId,
-            req.futureVersion());
+        GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(ctx.cacheId(), nodeId, req.futureVersion(),
+            ctx.deploymentEnabled());
 
         List<KeyCacheObject> keys = req.keys();
 
@@ -2480,7 +2479,8 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
         GridCacheVersion ver = req.writeVersion();
 
         // Always send update reply.
-        GridDhtAtomicUpdateResponse res = new GridDhtAtomicUpdateResponse(ctx.cacheId(), req.futureVersion());
+        GridDhtAtomicUpdateResponse res = new GridDhtAtomicUpdateResponse(ctx.cacheId(), req.futureVersion(),
+            ctx.deploymentEnabled());
 
         Boolean replicate = ctx.isDrEnabled();
 
@@ -2936,7 +2936,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
          */
         private void finish() {
             GridDhtAtomicDeferredUpdateResponse msg = new GridDhtAtomicDeferredUpdateResponse(ctx.cacheId(),
-                respVers);
+                respVers, ctx.deploymentEnabled());
 
             try {
                 ctx.kernalContext().gateway().readLock();
@@ -2966,4 +2966,4 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
             pendingResponses.remove(nodeId, this);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicDeferredUpdateResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicDeferredUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicDeferredUpdateResponse.java
index f3ecdb4..3a7bf1c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicDeferredUpdateResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicDeferredUpdateResponse.java
@@ -58,13 +58,21 @@ public class GridDhtAtomicDeferredUpdateResponse extends GridCacheMessage implem
     /**
      * Constructor.
      *
+     * @param cacheId Cache ID.
      * @param futVers Future versions.
+     * @param addDepInfo Deployment info.
      */
-    public GridDhtAtomicDeferredUpdateResponse(int cacheId, Collection<GridCacheVersion> futVers) {
+    public GridDhtAtomicDeferredUpdateResponse(int cacheId, Collection<GridCacheVersion> futVers, boolean addDepInfo) {
         assert !F.isEmpty(futVers);
 
         this.cacheId = cacheId;
         this.futVers = futVers;
+        this.addDepInfo = addDepInfo;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
     }
 
     /**
@@ -133,4 +141,4 @@ public class GridDhtAtomicDeferredUpdateResponse extends GridCacheMessage implem
     @Override public byte fieldsCount() {
         return 4;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
index 35b8e27..4ace5c4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java
@@ -233,7 +233,8 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
                         forceTransformBackups,
                         this.updateReq.subjectId(),
                         this.updateReq.taskNameHash(),
-                        forceTransformBackups ? this.updateReq.invokeArguments() : null);
+                        forceTransformBackups ? this.updateReq.invokeArguments() : null,
+                        cctx.deploymentEnabled());
 
                     mappings.put(nodeId, updateReq);
                 }
@@ -288,7 +289,8 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter<Void>
                     forceTransformBackups,
                     this.updateReq.subjectId(),
                     this.updateReq.taskNameHash(),
-                    forceTransformBackups ? this.updateReq.invokeArguments() : null);
+                    forceTransformBackups ? this.updateReq.invokeArguments() : null,
+                    cctx.deploymentEnabled());
 
                 mappings.put(nodeId, updateReq);
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
index f5231ef..e55cac9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java
@@ -159,6 +159,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
      * @param forceTransformBackups Force transform backups flag.
      * @param subjId Subject ID.
      * @param taskNameHash Task name hash code.
+     * @param addDepInfo Deployment info.
      */
     public GridDhtAtomicUpdateRequest(
         int cacheId,
@@ -170,7 +171,8 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
         boolean forceTransformBackups,
         UUID subjId,
         int taskNameHash,
-        Object[] invokeArgs
+        Object[] invokeArgs,
+        boolean addDepInfo
     ) {
         assert invokeArgs == null || forceTransformBackups;
 
@@ -184,6 +186,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
         this.subjId = subjId;
         this.taskNameHash = taskNameHash;
         this.invokeArgs = invokeArgs;
+        this.addDepInfo = addDepInfo;
 
         keys = new ArrayList<>();
 
@@ -546,13 +549,16 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
         prepareMarshalCacheObjects(nearVals, cctx);
 
         if (forceTransformBackups) {
-            invokeArgsBytes = marshalInvokeArguments(invokeArgs, ctx);
+            // force addition of deployment info for entry processors if P2P is enabled globally.
+            if (!addDepInfo && ctx.deploymentEnabled())
+                addDepInfo = true;
 
-            entryProcessorsBytes = marshalCollection(entryProcessors, ctx);
-        }
+            invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx);
 
-        if (forceTransformBackups)
-            nearEntryProcessorsBytes = marshalCollection(nearEntryProcessors, ctx);
+            entryProcessorsBytes = marshalCollection(entryProcessors, cctx);
+
+            nearEntryProcessorsBytes = marshalCollection(nearEntryProcessors, cctx);
+        }
     }
 
     /** {@inheritDoc} */
@@ -580,6 +586,11 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -913,4 +924,4 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage implements Grid
     @Override public String toString() {
         return S.toString(GridDhtAtomicUpdateRequest.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java
index 04d36e5..f1bb323 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateResponse.java
@@ -77,10 +77,12 @@ public class GridDhtAtomicUpdateResponse extends GridCacheMessage implements Gri
     /**
      * @param cacheId Cache ID.
      * @param futVer Future version.
+     * @param addDepInfo Deployment info.
      */
-    public GridDhtAtomicUpdateResponse(int cacheId, GridCacheVersion futVer) {
+    public GridDhtAtomicUpdateResponse(int cacheId, GridCacheVersion futVer, boolean addDepInfo) {
         this.cacheId = cacheId;
         this.futVer = futVer;
+        this.addDepInfo = addDepInfo;
     }
 
     /** {@inheritDoc} */
@@ -180,6 +182,11 @@ public class GridDhtAtomicUpdateResponse extends GridCacheMessage implements Gri
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -285,4 +292,4 @@ public class GridDhtAtomicUpdateResponse extends GridCacheMessage implements Gri
     @Override public String toString() {
         return S.toString(GridDhtAtomicUpdateResponse.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
index 97aa646..ae662c8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java
@@ -583,7 +583,8 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter<Object>
                     req = mappings != null ? mappings.get(nodeId) : null;
 
                 if (req != null) {
-                    res = new GridNearAtomicUpdateResponse(cctx.cacheId(), nodeId, req.futureVersion());
+                    res = new GridNearAtomicUpdateResponse(cctx.cacheId(), nodeId, req.futureVersion(),
+                        cctx.deploymentEnabled());
 
                     ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Primary node left grid " +
                         "before response is received: " + nodeId);
@@ -794,7 +795,8 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter<Object>
             synchronized (this) {
                 GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse(cctx.cacheId(),
                     req.nodeId(),
-                    req.futureVersion());
+                    req.futureVersion(),
+                    cctx.deploymentEnabled());
 
                 res.addFailedKeys(req.keys(), e);
 
@@ -1048,7 +1050,8 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter<Object>
                             subjId,
                             taskNameHash,
                             skipStore,
-                            cctx.kernalContext().clientNode());
+                            cctx.kernalContext().clientNode(),
+                            cctx.deploymentEnabled());
 
                         pendingMappings.put(nodeId, mapped);
                     }
@@ -1140,7 +1143,8 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter<Object>
                 subjId,
                 taskNameHash,
                 skipStore,
-                cctx.kernalContext().clientNode());
+                cctx.kernalContext().clientNode(),
+                cctx.deploymentEnabled());
 
             req.addUpdateEntry(cacheKey,
                 val,

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java
index ccb67d2..33fa4bd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java
@@ -178,6 +178,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage implements Gri
      * @param taskNameHash Task name hash code.
      * @param skipStore Skip write-through to a persistent storage.
      * @param clientReq Client node request flag.
+     * @param addDepInfo Deployment info flag.
      */
     public GridNearAtomicUpdateRequest(
         int cacheId,
@@ -196,7 +197,8 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage implements Gri
         @Nullable UUID subjId,
         int taskNameHash,
         boolean skipStore,
-        boolean clientReq
+        boolean clientReq,
+        boolean addDepInfo
     ) {
         assert futVer != null;
 
@@ -218,6 +220,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage implements Gri
         this.taskNameHash = taskNameHash;
         this.skipStore = skipStore;
         this.clientReq = clientReq;
+        this.addDepInfo = addDepInfo;
 
         keys = new ArrayList<>();
     }
@@ -538,11 +541,6 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage implements Gri
 
         prepareMarshalCacheObjects(keys, cctx);
 
-        if (op == TRANSFORM)
-            entryProcessorsBytes = marshalCollection(entryProcessors, ctx);
-        else
-            prepareMarshalCacheObjects(vals, cctx);
-
         if (filter != null) {
             boolean hasFilter = false;
 
@@ -558,10 +556,20 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage implements Gri
                 filter = null;
         }
 
-        invokeArgsBytes = marshalInvokeArguments(invokeArgs, ctx);
-
         if (expiryPlc != null)
-            expiryPlcBytes = CU.marshal(ctx, new IgniteExternalizableExpiryPolicy(expiryPlc));
+            expiryPlcBytes = CU.marshal(cctx, new IgniteExternalizableExpiryPolicy(expiryPlc));
+
+        if (op == TRANSFORM) {
+            // force addition of deployment info for entry processors if P2P is enabled globally.
+            if (!addDepInfo && ctx.deploymentEnabled())
+                addDepInfo = true;
+
+            entryProcessorsBytes = marshalCollection(entryProcessors, cctx);
+
+            invokeArgsBytes = marshalInvokeArguments(invokeArgs, cctx);
+        }
+        else
+            prepareMarshalCacheObjects(vals, cctx);
     }
 
     /** {@inheritDoc} */
@@ -591,6 +599,11 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage implements Gri
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -957,4 +970,4 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage implements Gri
         return S.toString(GridNearAtomicUpdateRequest.class, this, "filter", Arrays.toString(filter),
             "parent", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java
index 376f4ec..6536af3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java
@@ -114,13 +114,15 @@ public class GridNearAtomicUpdateResponse extends GridCacheMessage implements Gr
      * @param cacheId Cache ID.
      * @param nodeId Node ID this reply should be sent to.
      * @param futVer Future version.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridNearAtomicUpdateResponse(int cacheId, UUID nodeId, GridCacheVersion futVer) {
+    public GridNearAtomicUpdateResponse(int cacheId, UUID nodeId, GridCacheVersion futVer, boolean addDepInfo) {
         assert futVer != null;
 
         this.cacheId = cacheId;
         this.nodeId = nodeId;
         this.futVer = futVer;
+        this.addDepInfo = addDepInfo;
     }
 
     /** {@inheritDoc} */
@@ -428,6 +430,11 @@ public class GridNearAtomicUpdateResponse extends GridCacheMessage implements Gr
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -631,4 +638,4 @@ public class GridNearAtomicUpdateResponse extends GridCacheMessage implements Gr
     @Override public String toString() {
         return S.toString(GridNearAtomicUpdateResponse.class, this, "parent");
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
index f38126d..6d69198 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
@@ -493,7 +493,8 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
                             GridNearUnlockRequest req = map.get(primary);
 
                             if (req == null) {
-                                map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt));
+                                map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt,
+                                    ctx.deploymentEnabled()));
 
                                 req.version(ver);
                             }
@@ -597,7 +598,8 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
                         GridNearUnlockRequest req = map.get(primary);
 
                         if (req == null) {
-                            map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt));
+                            map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt,
+                                ctx.deploymentEnabled()));
 
                             req.version(ver);
                         }
@@ -896,4 +898,4 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
     @Override public String toString() {
         return S.toString(GridDhtColocatedCache.class, this, super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 be09f54..53c2b63 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
@@ -849,7 +849,8 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
                                         inTx() ? tx.taskNameHash() : 0,
                                         read ? accessTtl : -1L,
                                         skipStore,
-                                        clientFirst);
+                                        clientFirst,
+                                        cctx.deploymentEnabled());
 
                                     mapping.request(req);
                                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysFuture.java
index eaed424..bb78748 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysFuture.java
@@ -266,7 +266,8 @@ public final class GridDhtForceKeysFuture<K, V> extends GridCompoundFuture<Objec
                         futId,
                         fut.miniId(),
                         mappedKeys,
-                        topVer);
+                        topVer,
+                        cctx.deploymentEnabled());
 
                     try {
                         add(fut); // Append new future.
@@ -588,4 +589,4 @@ public final class GridDhtForceKeysFuture<K, V> extends GridCompoundFuture<Objec
             return S.toString(MiniFuture.class, this, super.toString());
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysRequest.java
index fac8b9b..15243d5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysRequest.java
@@ -59,18 +59,27 @@ public class GridDhtForceKeysRequest extends GridCacheMessage implements GridCac
     private AffinityTopologyVersion topVer;
 
     /**
+     * Required by {@link Externalizable}.
+     */
+    public GridDhtForceKeysRequest() {
+        // No-op.
+    }
+
+    /**
      * @param cacheId Cache ID.
      * @param futId Future ID.
      * @param miniId Mini-future ID.
      * @param keys Keys.
      * @param topVer Topology version.
+     * @param addDepInfo Deployment info.
      */
     GridDhtForceKeysRequest(
         int cacheId,
         IgniteUuid futId,
         IgniteUuid miniId,
         Collection<KeyCacheObject> keys,
-        AffinityTopologyVersion topVer
+        AffinityTopologyVersion topVer,
+        boolean addDepInfo
     ) {
         assert futId != null;
         assert miniId != null;
@@ -81,22 +90,7 @@ public class GridDhtForceKeysRequest extends GridCacheMessage implements GridCac
         this.miniId = miniId;
         this.keys = keys;
         this.topVer = topVer;
-    }
-
-    /**
-     * Required by {@link Externalizable}.
-     */
-    public GridDhtForceKeysRequest() {
-        // No-op.
-    }
-
-    /**
-     * @param keys Collection of keys.
-     */
-    public GridDhtForceKeysRequest(Collection<KeyCacheObject> keys) {
-        assert !F.isEmpty(keys);
-
-        this.keys = keys;
+        this.addDepInfo = addDepInfo;
     }
 
     /**
@@ -146,6 +140,11 @@ public class GridDhtForceKeysRequest extends GridCacheMessage implements GridCac
         finishUnmarshalCacheObjects(keys, cctx, ldr);
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
     /**
      * @return Key count.
      */
@@ -259,4 +258,4 @@ public class GridDhtForceKeysRequest extends GridCacheMessage implements GridCac
     @Override public String toString() {
         return S.toString(GridDhtForceKeysRequest.class, this, "keyCnt", keyCount(), "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysResponse.java
index 9418887..4cdecec 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtForceKeysResponse.java
@@ -80,14 +80,16 @@ public class GridDhtForceKeysResponse extends GridCacheMessage implements GridCa
      * @param cacheId Cache ID.
      * @param futId Request id.
      * @param miniId Mini-future ID.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridDhtForceKeysResponse(int cacheId, IgniteUuid futId, IgniteUuid miniId) {
+    public GridDhtForceKeysResponse(int cacheId, IgniteUuid futId, IgniteUuid miniId, boolean addDepInfo) {
         assert futId != null;
         assert miniId != null;
 
         this.cacheId = cacheId;
         this.futId = futId;
         this.miniId = miniId;
+        this.addDepInfo = addDepInfo;
     }
 
     /**
@@ -189,6 +191,11 @@ public class GridDhtForceKeysResponse extends GridCacheMessage implements GridCa
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -308,4 +315,4 @@ public class GridDhtForceKeysResponse extends GridCacheMessage implements GridCa
     @Override public String toString() {
         return S.toString(GridDhtForceKeysResponse.class, this, super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java
index 848ad87..7609d98 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java
@@ -189,6 +189,11 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessage.java
index 190946b..7a07f9a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessage.java
@@ -78,14 +78,16 @@ public class GridDhtPartitionSupplyMessage extends GridCacheMessage implements G
      * @param workerId Worker ID.
      * @param updateSeq Update sequence for this node.
      * @param cacheId Cache ID.
+     * @param addDepInfo Deployment info flag.
      */
-    GridDhtPartitionSupplyMessage(int workerId, long updateSeq, int cacheId) {
+    GridDhtPartitionSupplyMessage(int workerId, long updateSeq, int cacheId, boolean addDepInfo) {
         assert workerId >= 0;
         assert updateSeq > 0;
 
         this.cacheId = cacheId;
         this.updateSeq = updateSeq;
         this.workerId = workerId;
+        this.addDepInfo = addDepInfo;
     }
 
     /**
@@ -258,6 +260,11 @@ public class GridDhtPartitionSupplyMessage extends GridCacheMessage implements G
         }
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
     /**
      * @return Number of entries in message.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyPool.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyPool.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyPool.java
index fe328ef..28a73b1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyPool.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyPool.java
@@ -253,7 +253,7 @@ class GridDhtPartitionSupplyPool {
             GridDhtPartitionDemandMessage d = msg.message();
 
             GridDhtPartitionSupplyMessage s = new GridDhtPartitionSupplyMessage(d.workerId(),
-                d.updateSequence(), cctx.cacheId());
+                d.updateSequence(), cctx.cacheId(), cctx.deploymentEnabled());
 
             long preloadThrottle = cctx.config().getRebalanceThrottle();
 
@@ -312,7 +312,7 @@ class GridDhtPartitionSupplyPool {
                                     U.sleep(preloadThrottle);
 
                                 s = new GridDhtPartitionSupplyMessage(d.workerId(), d.updateSequence(),
-                                    cctx.cacheId());
+                                    cctx.cacheId(), cctx.deploymentEnabled());
                             }
 
                             GridCacheEntryInfo info = e.info();
@@ -364,7 +364,7 @@ class GridDhtPartitionSupplyPool {
                                                 U.sleep(preloadThrottle);
 
                                             s = new GridDhtPartitionSupplyMessage(d.workerId(),
-                                                d.updateSequence(), cctx.cacheId());
+                                                d.updateSequence(), cctx.cacheId(), cctx.deploymentEnabled());
                                         }
 
                                         GridCacheSwapEntry swapEntry = e.getValue();
@@ -448,7 +448,7 @@ class GridDhtPartitionSupplyPool {
 
                                     s = new GridDhtPartitionSupplyMessage(d.workerId(),
                                         d.updateSequence(),
-                                        cctx.cacheId());
+                                        cctx.cacheId(), cctx.deploymentEnabled());
                                 }
 
                                 if (preloadPred == null || preloadPred.apply(info))
@@ -552,4 +552,4 @@ class GridDhtPartitionSupplyPool {
             return "DemandMessage [senderId=" + senderId() + ", msg=" + message() + ']';
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsAbstractMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsAbstractMessage.java
index 041d5f0..4e714ed 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsAbstractMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsAbstractMessage.java
@@ -56,6 +56,11 @@ abstract class GridDhtPartitionsAbstractMessage extends GridCacheMessage {
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean partitionExchangeMessage() {
         return true;
     }
@@ -142,4 +147,4 @@ abstract class GridDhtPartitionsAbstractMessage extends GridCacheMessage {
     @Override public String toString() {
         return S.toString(GridDhtPartitionsAbstractMessage.class, this, super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
index 74237f8..83867f4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
@@ -372,7 +372,8 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
             GridDhtForceKeysResponse res = new GridDhtForceKeysResponse(
                 cctx.cacheId(),
                 msg.futureId(),
-                msg.miniId());
+                msg.miniId(),
+                cctx.deploymentEnabled());
 
             for (KeyCacheObject k : msg.keys()) {
                 int p = cctx.affinity().partition(k);

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
index d9763f8..eca2f71 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
@@ -410,7 +410,8 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                     subjId,
                     taskName == null ? 0 : taskName.hashCode(),
                     expiryPlc != null ? expiryPlc.forAccess() : -1L,
-                    skipVals);
+                    skipVals,
+                    cctx.deploymentEnabled());
 
                 add(fut); // Append new future.
 
@@ -947,4 +948,4 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
             return S.toString(MiniFuture.class, this);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
index 9bd2a68..ff6375a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
@@ -116,6 +116,7 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
      * @param subjId Subject ID.
      * @param taskNameHash Task name hash.
      * @param accessTtl New TTL to set after entry is accessed, -1 to leave unchanged.
+     * @param addDepInfo Deployment info.
      */
     public GridNearGetRequest(
         int cacheId,
@@ -129,7 +130,8 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
         UUID subjId,
         int taskNameHash,
         long accessTtl,
-        boolean skipVals
+        boolean skipVals,
+        boolean addDepInfo
     ) {
         assert futId != null;
         assert miniId != null;
@@ -149,6 +151,7 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
         this.taskNameHash = taskNameHash;
         this.accessTtl = accessTtl;
         this.skipVals = skipVals;
+        this.addDepInfo = addDepInfo;
     }
 
     /**
@@ -272,6 +275,11 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -490,4 +498,4 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
     @Override public String toString() {
         return S.toString(GridNearGetRequest.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java
index d4493a2..fc06ab1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetResponse.java
@@ -90,12 +90,14 @@ public class GridNearGetResponse extends GridCacheMessage implements GridCacheDe
      * @param futId Future ID.
      * @param miniId Sub ID.
      * @param ver Version.
+     * @param addDepInfo Deployment info.
      */
     public GridNearGetResponse(
         int cacheId,
         IgniteUuid futId,
         IgniteUuid miniId,
-        GridCacheVersion ver
+        GridCacheVersion ver,
+        boolean addDepInfo
     ) {
         assert futId != null;
         assert miniId != null;
@@ -105,6 +107,7 @@ public class GridNearGetResponse extends GridCacheMessage implements GridCacheDe
         this.futId = futId;
         this.miniId = miniId;
         this.ver = ver;
+        this.addDepInfo = addDepInfo;
     }
 
     /**
@@ -207,6 +210,11 @@ public class GridNearGetResponse extends GridCacheMessage implements GridCacheDe
     }
 
     /** {@inheritDoc} */
+    @Override public boolean addDeploymentInfo() {
+        return addDepInfo;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
 
@@ -354,4 +362,4 @@ public class GridNearGetResponse extends GridCacheMessage implements GridCacheDe
     @Override public String toString() {
         return S.toString(GridNearGetResponse.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 e6b1e02..c5b55bd 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
@@ -968,7 +968,8 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture<Boolean
                                             inTx() ? tx.taskNameHash() : 0,
                                             read ? accessTtl : -1L,
                                             skipStore,
-                                            clientFirst);
+                                            clientFirst,
+                                            cctx.deploymentEnabled());
 
                                         mapping.request(req);
                                     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
index 25ab297..165da84 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
@@ -121,6 +121,7 @@ public class GridNearLockRequest extends GridDistributedLockRequest {
      * @param accessTtl TTL for read operation.
      * @param skipStore Skip store flag.
      * @param firstClientReq {@code True} if first lock request for lock operation sent from client node.
+     * @param addDepInfo Deployment info flag.
      */
     public GridNearLockRequest(
         int cacheId,
@@ -144,7 +145,9 @@ public class GridNearLockRequest extends GridDistributedLockRequest {
         int taskNameHash,
         long accessTtl,
         boolean skipStore,
-        boolean firstClientReq
+        boolean firstClientReq,
+        boolean addDepInfo
+
     ) {
         super(
             cacheId,
@@ -160,7 +163,8 @@ public class GridNearLockRequest extends GridDistributedLockRequest {
             timeout,
             keyCnt,
             txSize,
-            skipStore);
+            skipStore,
+            addDepInfo);
 
         assert topVer.compareTo(AffinityTopologyVersion.ZERO) > 0;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java
index 581061c..e48a098 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockResponse.java
@@ -79,6 +79,7 @@ public class GridNearLockResponse extends GridDistributedLockResponse {
      * @param cnt Count.
      * @param err Error.
      * @param clientRemapVer {@code True} if client node should remap lock request.
+     * @param addDepInfo Deployment info.
      */
     public GridNearLockResponse(
         int cacheId,
@@ -88,9 +89,10 @@ public class GridNearLockResponse extends GridDistributedLockResponse {
         boolean filterRes,
         int cnt,
         Throwable err,
-        AffinityTopologyVersion clientRemapVer
+        AffinityTopologyVersion clientRemapVer,
+        boolean addDepInfo
     ) {
-        super(cacheId, lockVer, futId, cnt, err);
+        super(cacheId, lockVer, futId, cnt, err, addDepInfo);
 
         assert miniId != null;
 
@@ -325,4 +327,4 @@ public class GridNearLockResponse extends GridDistributedLockResponse {
     @Override public String toString() {
         return S.toString(GridNearLockResponse.class, this, super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 1fb33a2..6db00ab 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
@@ -588,7 +588,8 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
             m.explicitLock(),
             tx.subjectId(),
             tx.taskNameHash(),
-            m.clientFirst());
+            m.clientFirst(),
+            tx.activeCachesDeploymentEnabled());
 
         for (IgniteTxEntry txEntry : m.writes()) {
             if (txEntry.op() == TRANSFORM)

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 b8d2250..62f9bb3 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
@@ -207,7 +207,8 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
                 m.explicitLock(),
                 tx.subjectId(),
                 tx.taskNameHash(),
-                false);
+                false,
+                tx.activeCachesDeploymentEnabled());
 
             for (IgniteTxEntry txEntry : m.writes()) {
                 if (txEntry.op() == TRANSFORM)

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 e70c864..c3bb324 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
@@ -554,7 +554,8 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
                             GridNearUnlockRequest req = map.get(primary);
 
                             if (req == null) {
-                                map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt));
+                                map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt,
+                                    ctx.deploymentEnabled()));
 
                                 req.version(ver);
                             }
@@ -676,7 +677,8 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
                                     req = map.get(primary);
 
                                     if (req == null) {
-                                        map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt));
+                                        map.put(primary, req = new GridNearUnlockRequest(ctx.cacheId(), keyCnt,
+                                            ctx.deploymentEnabled()));
 
                                         req.version(ver);
                                     }
@@ -740,4 +742,4 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
     @Override public String toString() {
         return S.toString(GridNearTransactionalCache.class, this);
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
index 85311cc..1a4f130 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
@@ -452,7 +452,8 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
                         null,
                         0,
                         null,
-                        0);
+                        0,
+                        tx.activeCachesDeploymentEnabled());
 
                     finishReq.checkCommitted(true);
 
@@ -574,7 +575,8 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
             null,
             tx.size(),
             tx.subjectId(),
-            tx.taskNameHash()
+            tx.taskNameHash(),
+            tx.activeCachesDeploymentEnabled()
         );
 
         // If this is the primary node for the keys.
@@ -764,4 +766,4 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
             return S.toString(MiniFuture.class, this, "done", isDone(), "cancelled", isCancelled(), "err", error());
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishRequest.java
index c52a127..3e5e28f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishRequest.java
@@ -77,6 +77,7 @@ public class GridNearTxFinishRequest extends GridDistributedTxFinishRequest {
      * @param committedVers Committed versions.
      * @param rolledbackVers Rolled back versions.
      * @param txSize Expected transaction size.
+     * @param addDepInfo Deployment info flag.
      */
     public GridNearTxFinishRequest(
         IgniteUuid futId,
@@ -96,7 +97,8 @@ public class GridNearTxFinishRequest extends GridDistributedTxFinishRequest {
         Collection<GridCacheVersion> rolledbackVers,
         int txSize,
         @Nullable UUID subjId,
-        int taskNameHash) {
+        int taskNameHash,
+        boolean addDepInfo) {
         super(
             xidVer,
             futId,
@@ -111,7 +113,8 @@ public class GridNearTxFinishRequest extends GridDistributedTxFinishRequest {
             baseVer,
             committedVers,
             rolledbackVers,
-            txSize
+            txSize,
+            addDepInfo
         );
 
         this.explicitLock = explicitLock;

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishResponse.java
index c860baa..4904ad8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishResponse.java
@@ -203,4 +203,4 @@ public class GridNearTxFinishResponse extends GridDistributedTxFinishResponse {
     @Override public String toString() {
         return S.toString(GridNearTxFinishResponse.class, this, "super", super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/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 2b3ddff..456d726 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
@@ -107,6 +107,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
      * @param subjId Subject ID.
      * @param taskNameHash Task name hash.
      * @param firstClientReq {@code True} if first optimistic tx prepare request sent from client node.
+     * @param addDepInfo Deployment info flag.
      */
     public GridNearTxPrepareRequest(
         IgniteUuid futId,
@@ -124,9 +125,10 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
         boolean explicitLock,
         @Nullable UUID subjId,
         int taskNameHash,
-        boolean firstClientReq
+        boolean firstClientReq,
+        boolean addDepInfo
     ) {
-        super(tx, reads, writes, txNodes, onePhaseCommit);
+        super(tx, reads, writes, txNodes, onePhaseCommit, addDepInfo);
 
         assert futId != null;
         assert !firstClientReq || tx.optimistic() : tx;
@@ -492,4 +494,4 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
     @Override public String toString() {
         return S.toString(GridNearTxPrepareRequest.class, this, super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java
index 6558f97..d886243 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareResponse.java
@@ -115,6 +115,7 @@ public class GridNearTxPrepareResponse extends GridDistributedTxPrepareResponse
      * @param retVal Return value.
      * @param err Error.
      * @param clientRemapVer Not {@code null} if client node should remap transaction.
+     * @param addDepInfo Deployment info flag.
      */
     public GridNearTxPrepareResponse(
         GridCacheVersion xid,
@@ -124,9 +125,10 @@ public class GridNearTxPrepareResponse extends GridDistributedTxPrepareResponse
         GridCacheVersion writeVer,
         GridCacheReturn retVal,
         Throwable err,
-        AffinityTopologyVersion clientRemapVer
+        AffinityTopologyVersion clientRemapVer,
+        boolean addDepInfo
     ) {
-        super(xid, err);
+        super(xid, err, addDepInfo);
 
         assert futId != null;
         assert miniId != null;
@@ -543,4 +545,4 @@ public class GridNearTxPrepareResponse extends GridDistributedTxPrepareResponse
         return S.toString(GridNearTxPrepareResponse.class, this, "super", super.toString());
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearUnlockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearUnlockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearUnlockRequest.java
index 821d504..7652a4a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearUnlockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearUnlockRequest.java
@@ -41,9 +41,10 @@ public class GridNearUnlockRequest extends GridDistributedUnlockRequest {
     /**
      * @param cacheId Cache ID.
      * @param keyCnt Key count.
+     * @param addDepInfo Deployment info flag.
      */
-    public GridNearUnlockRequest(int cacheId, int keyCnt) {
-        super(cacheId, keyCnt);
+    public GridNearUnlockRequest(int cacheId, int keyCnt, boolean addDepInfo) {
+        super(cacheId, keyCnt, addDepInfo);
     }
 
     /** {@inheritDoc} */
@@ -90,4 +91,4 @@ public class GridNearUnlockRequest extends GridDistributedUnlockRequest {
     @Override public String toString() {
         return S.toString(GridNearUnlockRequest.class, this, super.toString());
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java
index d064601..d5916e3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java
@@ -41,13 +41,15 @@ public class CacheObjectPortableContext extends CacheObjectContext {
      * @param portableEnabled Portable enabled flag.
      * @param cpyOnGet Copy on get flag.
      * @param storeVal {@code True} if should store unmarshalled value in cache.
+     * @param depEnabled {@code true} if deployment is enabled for the given cache.
      */
     public CacheObjectPortableContext(GridKernalContext kernalCtx,
         boolean cpyOnGet,
         boolean storeVal,
-        boolean portableEnabled) {
+        boolean portableEnabled,
+        boolean depEnabled) {
         super(kernalCtx, portableEnabled ? new CacheDefaultPortableAffinityKeyMapper() :
-            new GridCacheDefaultAffinityKeyMapper(), cpyOnGet, storeVal);
+            new GridCacheDefaultAffinityKeyMapper(), cpyOnGet, storeVal, depEnabled);
 
         this.portableEnabled = portableEnabled;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableProcessorImpl.java
index 4cab3db..2de9d84 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableProcessorImpl.java
@@ -704,7 +704,8 @@ public class CacheObjectPortableProcessorImpl extends IgniteCacheObjectProcessor
         CacheObjectContext res = new CacheObjectPortableContext(ctx,
             ctx0.copyOnGet(),
             ctx0.storeValue(),
-            portableEnabled);
+            portableEnabled,
+            ctx0.addDeploymentInfo());
 
         ctx.resource().injectGeneric(res.defaultAffMapper());
 
@@ -1022,4 +1023,4 @@ public class CacheObjectPortableProcessorImpl extends IgniteCacheObjectProcessor
             return S.toString(MetaDataPredicate.class, this);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/df931bd0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryFuture.java
index e745e30..6110e0c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheDistributedQueryFuture.java
@@ -102,7 +102,8 @@ public class GridCacheDistributedQueryFuture<K, V, R> extends GridCacheQueryFutu
             final GridCacheQueryRequest req = new GridCacheQueryRequest(cctx.cacheId(),
                 reqId,
                 fields(),
-                qryMgr.queryTopologyVersion());
+                qryMgr.queryTopologyVersion(),
+                cctx.deploymentEnabled());
 
             // Process cancel query directly (without sending) for local node,
             cctx.closures().callLocalSafe(new Callable<Object>() {
@@ -275,4 +276,4 @@ public class GridCacheDistributedQueryFuture<K, V, R> extends GridCacheQueryFutu
 
         qryMgr.removeQueryFuture(reqId);
     }
-}
\ No newline at end of file
+}


[15/31] ignite git commit: Exclude neighbors flag for affinity functions. This closes #80

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
index a4737c2..d2904e87 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
@@ -22,10 +22,10 @@ import junit.framework.TestSuite;
 import org.apache.ignite.GridCacheAffinityBackupsSelfTest;
 import org.apache.ignite.IgniteCacheAffinitySelfTest;
 import org.apache.ignite.cache.IgniteWarmupClosureSelfTest;
-import org.apache.ignite.cache.affinity.IgniteClientNodeAffinityTest;
-import org.apache.ignite.cache.affinity.fair.GridFairAffinityFunctionNodesSelfTest;
-import org.apache.ignite.cache.affinity.fair.GridFairAffinityFunctionSelfTest;
-import org.apache.ignite.cache.affinity.fair.IgniteFairAffinityDynamicCacheSelfTest;
+import org.apache.ignite.cache.affinity.AffinityClientNodeSelfTest;
+import org.apache.ignite.cache.affinity.fair.FairAffinityDynamicCacheSelfTest;
+import org.apache.ignite.cache.affinity.fair.FairAffinityFunctionNodesSelfTest;
+import org.apache.ignite.cache.affinity.fair.FairAffinityFunctionSelfTest;
 import org.apache.ignite.cache.store.GridCacheBalancingStoreSelfTest;
 import org.apache.ignite.cache.store.GridCacheLoadOnlyStoreAdapterSelfTest;
 import org.apache.ignite.cache.store.StoreResourceInjectionSelfTest;
@@ -183,12 +183,12 @@ public class IgniteCacheTestSuite extends TestSuite {
         suite.addTestSuite(IgniteWarmupClosureSelfTest.class);
 
         // Affinity tests.
-        suite.addTestSuite(GridFairAffinityFunctionNodesSelfTest.class);
-        suite.addTestSuite(GridFairAffinityFunctionSelfTest.class);
-        suite.addTestSuite(IgniteFairAffinityDynamicCacheSelfTest.class);
+        suite.addTestSuite(FairAffinityFunctionNodesSelfTest.class);
+        suite.addTestSuite(FairAffinityFunctionSelfTest.class);
+        suite.addTestSuite(FairAffinityDynamicCacheSelfTest.class);
         suite.addTestSuite(GridCacheAffinityBackupsSelfTest.class);
         suite.addTestSuite(IgniteCacheAffinitySelfTest.class);
-        suite.addTestSuite(IgniteClientNodeAffinityTest.class);
+        suite.addTestSuite(AffinityClientNodeSelfTest.class);
 
         // Swap tests.
         suite.addTestSuite(GridCacheSwapPreloadSelfTest.class);

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
index bd24e51..93bd26c 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
@@ -18,6 +18,10 @@
 package org.apache.ignite.testsuites;
 
 import junit.framework.TestSuite;
+import org.apache.ignite.cache.affinity.fair.FairAffinityFunctionBackupFilterSelfTest;
+import org.apache.ignite.cache.affinity.fair.FairAffinityFunctionExcludeNeighborsSelfTest;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionBackupFilterSelfTest;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunctionExcludeNeighborsSelfTest;
 import org.apache.ignite.internal.processors.cache.CacheDhtLocalPartitionAfterRemoveSelfTest;
 import org.apache.ignite.internal.processors.cache.CrossCacheTxRandomOperationsTest;
 import org.apache.ignite.internal.processors.cache.GridCacheAtomicMessageCountSelfTest;
@@ -32,7 +36,6 @@ import org.apache.ignite.internal.processors.cache.IgniteCachePartitionMapUpdate
 import org.apache.ignite.internal.processors.cache.IgniteDynamicCacheAndNodeStop;
 import org.apache.ignite.internal.processors.cache.distributed.CacheLoadingConcurrentGridStartSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.GridCachePartitionNotLoadedEventSelfTest;
-import org.apache.ignite.internal.processors.cache.distributed.GridCachePartitionedAffinityFilterSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.GridCacheTransformEventSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheClientNodeChangingTopologyTest;
 import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheClientNodePartitionsExchangeTest;
@@ -101,7 +104,6 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePar
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedTxSingleThreadedSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedTxTimeoutSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheRendezvousAffinityClientSelfTest;
-import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheRendezvousAffinityFunctionExcludeNeighborsSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridPartitionedBackupLoadSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.NoneRebalanceModeSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedEvictionSelfTest;
@@ -162,7 +164,8 @@ public class IgniteCacheTestSuite2 extends TestSuite {
         suite.addTest(new TestSuite(GridCacheNearReaderPreloadSelfTest.class));
         suite.addTest(new TestSuite(GridCacheAtomicNearReadersSelfTest.class));
         suite.addTest(new TestSuite(GridCachePartitionedAffinitySelfTest.class));
-        suite.addTest(new TestSuite(GridCacheRendezvousAffinityFunctionExcludeNeighborsSelfTest.class));
+        suite.addTest(new TestSuite(RendezvousAffinityFunctionExcludeNeighborsSelfTest.class));
+        suite.addTest(new TestSuite(FairAffinityFunctionExcludeNeighborsSelfTest.class));
         suite.addTest(new TestSuite(GridCacheRendezvousAffinityClientSelfTest.class));
         suite.addTest(new TestSuite(GridCachePartitionedProjectionAffinitySelfTest.class));
         suite.addTest(new TestSuite(GridCachePartitionedBasicOpSelfTest.class));
@@ -198,7 +201,8 @@ public class IgniteCacheTestSuite2 extends TestSuite {
         suite.addTest(new TestSuite(GridCacheNearPreloadRestartSelfTest.class));
         suite.addTest(new TestSuite(GridCacheDhtPreloadStartStopSelfTest.class));
         suite.addTest(new TestSuite(GridCacheDhtPreloadUnloadSelfTest.class));
-        suite.addTest(new TestSuite(GridCachePartitionedAffinityFilterSelfTest.class));
+        suite.addTest(new TestSuite(RendezvousAffinityFunctionBackupFilterSelfTest.class));
+        suite.addTest(new TestSuite(FairAffinityFunctionBackupFilterSelfTest.class));
         suite.addTest(new TestSuite(GridCachePartitionedPreloadLifecycleSelfTest.class));
         suite.addTest(new TestSuite(CacheLoadingConcurrentGridStartSelfTest.class));
         suite.addTest(new TestSuite(GridCacheDhtPreloadDelayedSelfTest.class));

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a180027/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
index cb39660..f3fbf15 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
@@ -47,6 +47,7 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.cache.query.QueryCursor;
 import org.apache.ignite.cache.query.ScanQuery;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
@@ -179,6 +180,9 @@ public abstract class IgniteCacheAbstractQuerySelfTest extends GridCommonAbstrac
                 IgniteCacheReplicatedQuerySelfTest.CacheKey.class, IgniteCacheReplicatedQuerySelfTest.CacheValue.class
             );
 
+            if (cacheMode() != CacheMode.LOCAL)
+                cc.setAffinity(new RendezvousAffinityFunction());
+
             // Explicitly set number of backups equal to number of grids.
             if (cacheMode() == CacheMode.PARTITIONED)
                 cc.setBackups(gridCount());


[20/31] ignite git commit: IGNITE-1747 Merge coding style adjustments in Ignite MQTT Streamer.

Posted by ra...@apache.org.
IGNITE-1747 Merge coding style adjustments in Ignite MQTT Streamer.


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

Branch: refs/heads/ignite-1790
Commit: db888607926d7ecc5bb54da7150c85013c56ee4e
Parents: 3ec52f3 6ca7a45
Author: Raul Kripalani <ra...@apache.org>
Authored: Tue Oct 27 16:04:27 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Tue Oct 27 16:05:02 2015 +0000

----------------------------------------------------------------------
 .../apache/ignite/stream/mqtt/MqttStreamer.java | 386 ++++++++++++-------
 .../stream/mqtt/IgniteMqttStreamerTest.java     | 142 +++++--
 .../mqtt/IgniteMqttStreamerTestSuite.java       |   4 +-
 3 files changed, 351 insertions(+), 181 deletions(-)
----------------------------------------------------------------------



[06/31] ignite git commit: Merge branch 'master' into ignite-1747

Posted by ra...@apache.org.
Merge branch 'master' into ignite-1747


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

Branch: refs/heads/ignite-1790
Commit: 6ca7a454acf1ebc8d344fdd5242c5f7e18e04d7f
Parents: b12663f ef785cb
Author: Raul Kripalani <ra...@apache.org>
Authored: Mon Oct 26 16:35:38 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Mon Oct 26 16:35:38 2015 +0000

----------------------------------------------------------------------
 DEVNOTES.txt                                    |   2 +-
 assembly/dependencies-fabric-lgpl.xml           | 169 +++++++++++++
 assembly/dependencies-fabric.xml                |   3 +
 assembly/release-fabric-base.xml                | 107 ++++++++
 assembly/release-fabric-lgpl.xml                |  41 ++--
 assembly/release-fabric.xml                     |  85 +------
 assembly/release-hadoop-lgpl.xml                |  39 ---
 config/fabric-lgpl/default-config.xml           |  29 +++
 examples-lgpl/README.txt                        |  27 --
 examples-lgpl/config/example-cache.xml          |  73 ------
 examples-lgpl/config/example-ignite.xml         |  83 -------
 examples-lgpl/config/hibernate/README.txt       |   8 -
 .../hibernate/example-hibernate-L2-cache.xml    |  64 -----
 examples-lgpl/pom-standalone.xml                | 186 --------------
 examples-lgpl/pom.xml                           | 128 ----------
 .../hibernate/HibernateL2CacheExample.java      | 245 -------------------
 .../examples/datagrid/hibernate/Post.java       | 130 ----------
 .../examples/datagrid/hibernate/User.java       | 154 ------------
 .../datagrid/hibernate/package-info.java        |  22 --
 .../hibernate/CacheHibernatePersonStore.java    | 122 ---------
 .../hibernate/CacheHibernateStoreExample.java   | 151 ------------
 .../datagrid/store/hibernate/Person.hbm.xml     |  34 ---
 .../datagrid/store/hibernate/hibernate.cfg.xml  |  41 ----
 .../datagrid/store/hibernate/package-info.java  |  22 --
 .../misc/schedule/ComputeScheduleExample.java   |  82 -------
 .../examples/misc/schedule/package-info.java    |  22 --
 .../misc/schedule/ComputeScheduleExample.java   |  68 -----
 .../java8/misc/schedule/package-info.java       |  22 --
 .../ignite/examples/java8/package-info.java     |  23 --
 .../scalar/examples/ScalarScheduleExample.scala |  66 -----
 ...ibernateL2CacheExampleMultiNodeSelfTest.java |  31 ---
 .../HibernateL2CacheExampleSelfTest.java        |  33 ---
 .../IgniteLgplExamplesSelfTestSuite.java        |  48 ----
 ...ibernateL2CacheExampleMultiNodeSelfTest.java |  29 ---
 .../HibernateL2CacheExampleSelfTest.java        |  37 ---
 .../IgniteLgplExamplesJ8SelfTestSuite.java      |  46 ----
 .../ScalarLgplExamplesMultiNodeSelfTest.scala   |  33 ---
 .../examples/ScalarLgplExamplesSelfTest.scala   |  36 ---
 .../ScalarLgplExamplesSelfTestSuite.scala       |  37 ---
 examples/README-LGPL.txt                        |  33 +++
 examples/README.txt                             |  21 +-
 examples/config/hibernate/README.txt            |   8 +
 .../hibernate/example-hibernate-L2-cache.xml    |  64 +++++
 examples/pom-standalone-lgpl.xml                | 217 ++++++++++++++++
 examples/pom-standalone.xml                     | 156 ++++++------
 examples/pom.xml                                | 157 ++++++------
 .../hibernate/HibernateL2CacheExample.java      | 245 +++++++++++++++++++
 .../examples/datagrid/hibernate/Post.java       | 130 ++++++++++
 .../examples/datagrid/hibernate/User.java       | 154 ++++++++++++
 .../datagrid/hibernate/package-info.java        |  22 ++
 .../hibernate/CacheHibernatePersonStore.java    | 122 +++++++++
 .../hibernate/CacheHibernateStoreExample.java   | 151 ++++++++++++
 .../datagrid/store/hibernate/Person.hbm.xml     |  34 +++
 .../datagrid/store/hibernate/hibernate.cfg.xml  |  41 ++++
 .../datagrid/store/hibernate/package-info.java  |  22 ++
 .../misc/schedule/ComputeScheduleExample.java   |  82 +++++++
 .../examples/misc/schedule/package-info.java    |  22 ++
 ...ibernateL2CacheExampleMultiNodeSelfTest.java |  31 +++
 .../HibernateL2CacheExampleSelfTest.java        |  33 +++
 .../IgniteLgplExamplesSelfTestSuite.java        |  48 ++++
 modules/core/src/test/config/tests.properties   |   4 +-
 modules/extdata/uri/pom.xml                     |  21 +-
 .../ipfinder/zk/ZookeeperIpFinderTestSuite.java |  32 +++
 pom.xml                                         |  64 -----
 64 files changed, 2022 insertions(+), 2470 deletions(-)
----------------------------------------------------------------------



[13/31] ignite git commit: ignite-1792: ContinuousProcessor should use ALWAYS_TRUE predicate instead of null

Posted by ra...@apache.org.
ignite-1792: ContinuousProcessor should use ALWAYS_TRUE predicate instead of null


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

Branch: refs/heads/ignite-1790
Commit: b5a30693498c17e5ecea04dd19c8608f54321076
Parents: e9aa4d1
Author: Andrey Gura <ag...@gridgain.com>
Authored: Tue Oct 27 14:03:27 2015 +0300
Committer: Denis Magda <dm...@gridgain.com>
Committed: Tue Oct 27 14:03:27 2015 +0300

----------------------------------------------------------------------
 .../cache/query/continuous/CacheContinuousQueryManager.java    | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b5a30693/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java
index 6a151a5..c7bf091 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryManager.java
@@ -419,10 +419,8 @@ public class CacheContinuousQueryManager extends GridCacheManagerAdapter {
             taskNameHash,
             skipPrimaryCheck);
 
-        IgnitePredicate<ClusterNode> pred = null;
-
-        if (loc || cctx.config().getCacheMode() == CacheMode.LOCAL)
-            pred = F.nodeForNodeId(cctx.localNodeId());
+        IgnitePredicate<ClusterNode> pred = (loc || cctx.config().getCacheMode() == CacheMode.LOCAL) ?
+            F.nodeForNodeId(cctx.localNodeId()) : F.<ClusterNode>alwaysTrue();
 
         UUID id = cctx.kernalContext().continuous().startRoutine(
             hnd,


[24/31] ignite git commit: ignite-1607 Implemented deadlock-free optimistic serializable tx mode

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 4074eee..c1e9202 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
@@ -25,12 +25,10 @@ import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.Map;
-import java.util.Queue;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ConcurrentNavigableMap;
-import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteClientDisconnectedException;
@@ -64,7 +62,6 @@ import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
 import org.apache.ignite.internal.util.GridBoundedConcurrentOrderedMap;
 import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
-import org.apache.ignite.internal.util.lang.GridFunc;
 import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.X;
@@ -78,7 +75,6 @@ import org.apache.ignite.transactions.TransactionIsolation;
 import org.apache.ignite.transactions.TransactionState;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
-import org.jsr166.ConcurrentLinkedDeque8;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_MAX_COMPLETED_TX_COUNT;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_SLOW_TX_WARN_TIMEOUT;
@@ -131,16 +127,6 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
     /** TX handler. */
     private IgniteTxHandler txHandler;
 
-    /** All transactions. */
-    private final Queue<IgniteInternalTx> committedQ = new ConcurrentLinkedDeque8<>();
-
-    /** Preparing transactions. */
-    private final Queue<IgniteInternalTx> prepareQ = new ConcurrentLinkedDeque8<>();
-
-    /** Minimum start version. */
-    private final ConcurrentNavigableMap<GridCacheVersion, AtomicInt> startVerCnts =
-        new ConcurrentSkipListMap<>();
-
     /** Committed local transactions. */
     private final GridBoundedConcurrentOrderedMap<GridCacheVersion, Boolean> completedVers =
         new GridBoundedConcurrentOrderedMap<>(Integer.getInteger(IGNITE_MAX_COMPLETED_TX_COUNT, DFLT_MAX_COMPLETED_TX_CNT));
@@ -308,41 +294,10 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
      * USE ONLY FOR MEMORY PROFILING DURING TESTS.
      */
     @Override public void printMemoryStats() {
-        IgniteInternalTx firstTx = committedQ.peek();
-
-        int committedSize = committedQ.size();
-
-        Map.Entry<GridCacheVersion, AtomicInt> startVerEntry = startVerCnts.firstEntry();
-
-        GridCacheVersion minStartVer = null;
-        long dur = 0;
-
-        if (committedSize > 3000) {
-            minStartVer = new GridCacheVersion(Integer.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, Integer.MAX_VALUE, 0);
-
-            IgniteInternalTx stuck = null;
-
-            for (IgniteInternalTx tx : txs())
-                if (tx.startVersion().isLess(minStartVer)) {
-                    minStartVer = tx.startVersion();
-                    dur = U.currentTimeMillis() - tx.startTime();
-
-                    stuck = tx;
-                }
-
-            X.println("Stuck transaction: " + stuck);
-        }
-
         X.println(">>> ");
         X.println(">>> Transaction manager memory stats [grid=" + cctx.gridName() + ']');
         X.println(">>>   threadMapSize: " + threadMap.size());
-        X.println(">>>   idMap [size=" + idMap.size() + ", minStartVer=" + minStartVer + ", dur=" + dur + "ms]");
-        X.println(">>>   committedQueue [size=" + committedSize +
-            ", firstStartVersion=" + (firstTx == null ? "null" : firstTx.startVersion()) +
-            ", firstEndVersion=" + (firstTx == null ? "null" : firstTx.endVersion()) + ']');
-        X.println(">>>   prepareQueueSize: " + prepareQ.size());
-        X.println(">>>   startVerCntsSize [size=" + startVerCnts.size() +
-            ", firstVer=" + startVerEntry + ']');
+        X.println(">>>   idMap [size=" + idMap.size() + ']');
         X.println(">>>   completedVersSize: " + completedVers.size());
     }
 
@@ -361,27 +316,6 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
     }
 
     /**
-     * @return Committed queue size.
-     */
-    public int commitQueueSize() {
-        return committedQ.size();
-    }
-
-    /**
-     * @return Prepare queue size.
-     */
-    public int prepareQueueSize() {
-        return prepareQ.size();
-    }
-
-    /**
-     * @return Start version counts.
-     */
-    public int startVersionCountsSize() {
-        return startVerCnts.size();
-    }
-
-    /**
      * @return Committed versions size.
      */
     public int completedVersionsSize() {
@@ -493,42 +427,6 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             return null;
         }
 
-        if (cctx.txConfig().isTxSerializableEnabled()) {
-            AtomicInt next = new AtomicInt(1);
-
-            boolean loop = true;
-
-            while (loop) {
-                AtomicInt prev = startVerCnts.putIfAbsent(tx.startVersion(), next);
-
-                if (prev == null)
-                    break; // Put succeeded - exit.
-
-                // Previous value was 0, which means that it will be deleted
-                // by another thread in "decrementStartVersionCount(..)" method.
-                // In that case, we delete here too, so we can safely try again.
-                for (;;) {
-                    int p = prev.get();
-
-                    assert p >= 0 : p;
-
-                    if (p == 0) {
-                        if (startVerCnts.remove(tx.startVersion(), prev))
-                            if (log.isDebugEnabled())
-                                log.debug("Removed count from onCreated callback: " + tx);
-
-                        break; // Retry outer loop.
-                    }
-
-                    if (prev.compareAndSet(p, p + 1)) {
-                        loop = false; // Increment succeeded - exit outer loop.
-
-                        break;
-                    }
-                }
-            }
-        }
-
         if (tx.timeout() > 0) {
             cctx.time().addTimeoutObject(tx);
 
@@ -822,117 +720,8 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             throw new IgniteTxTimeoutCheckedException("Transaction timed out: " + this);
         }
 
-        boolean txSerEnabled = cctx.txConfig().isTxSerializableEnabled();
-
-        // Clean up committed transactions queue.
-        if (tx.pessimistic() && tx.local()) {
-            if (tx.enforceSerializable() && txSerEnabled) {
-                for (Iterator<IgniteInternalTx> it = committedQ.iterator(); it.hasNext();) {
-                    IgniteInternalTx committedTx = it.next();
-
-                    assert committedTx != tx;
-
-                    // Clean up.
-                    if (isSafeToForget(committedTx))
-                        it.remove();
-                }
-            }
-
-            // Nothing else to do in pessimistic mode.
-            return;
-        }
-
-        if (txSerEnabled && tx.optimistic() && tx.enforceSerializable()) {
-            Set<IgniteTxKey> readSet = tx.readSet();
-            Set<IgniteTxKey> writeSet = tx.writeSet();
-
-            GridCacheVersion startTn = tx.startVersion();
-
-            GridCacheVersion finishTn = cctx.versions().last();
-
-            // Add future to prepare queue only on first prepare call.
-            if (tx.markPreparing())
-                prepareQ.offer(tx);
-
-            // Check that our read set does not intersect with write set
-            // of all transactions that completed their write phase
-            // while our transaction was in read phase.
-            for (Iterator<IgniteInternalTx> it = committedQ.iterator(); it.hasNext();) {
-                IgniteInternalTx committedTx = it.next();
-
-                assert committedTx != tx;
-
-                // Clean up.
-                if (isSafeToForget(committedTx)) {
-                    it.remove();
-
-                    continue;
-                }
-
-                GridCacheVersion tn = committedTx.endVersion();
-
-                // We only care about transactions
-                // with tn > startTn and tn <= finishTn
-                if (tn.compareTo(startTn) <= 0 || tn.compareTo(finishTn) > 0)
-                    continue;
-
-                if (tx.serializable()) {
-                    if (GridFunc.intersects(committedTx.writeSet(), readSet)) {
-                        tx.setRollbackOnly();
-
-                        throw new IgniteTxOptimisticCheckedException("Failed to prepare transaction " +
-                            "(committed vs. read-set conflict): " + tx);
-                    }
-                }
-            }
-
-            // Check that our read and write sets do not intersect with write
-            // sets of all active transactions.
-            for (Iterator<IgniteInternalTx> iter = prepareQ.iterator(); iter.hasNext();) {
-                IgniteInternalTx prepareTx = iter.next();
-
-                if (prepareTx == tx)
-                    // Skip yourself.
-                    continue;
-
-                // Optimistically remove completed transactions.
-                if (prepareTx.done()) {
-                    iter.remove();
-
-                    if (log.isDebugEnabled())
-                        log.debug("Removed finished transaction from active queue: " + prepareTx);
-
-                    continue;
-                }
-
-                // Check if originating node left.
-                if (cctx.discovery().node(prepareTx.nodeId()) == null) {
-                    iter.remove();
-
-                    rollbackTx(prepareTx);
-
-                    if (log.isDebugEnabled())
-                        log.debug("Removed and rolled back transaction because sender node left grid: " +
-                            CU.txString(prepareTx));
-
-                    continue;
-                }
-
-                if (tx.serializable() && !prepareTx.isRollbackOnly()) {
-                    Set<IgniteTxKey> prepareWriteSet = prepareTx.writeSet();
-
-                    if (GridFunc.intersects(prepareWriteSet, readSet, writeSet)) {
-                        // Remove from active set.
-                        iter.remove();
-
-                        tx.setRollbackOnly();
-
-                        throw new IgniteTxOptimisticCheckedException(
-                            "Failed to prepare transaction (read-set/write-set conflict): " + tx);
-                    }
-                }
-            }
-        }
+        if (tx.pessimistic() && tx.local())
+            return; // Nothing else to do in pessimistic mode.
 
         // Optimistic.
         assert tx.optimistic() || !tx.local();
@@ -945,40 +734,6 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
     }
 
     /**
-     * @param tx Transaction to check.
-     * @return {@code True} if transaction can be discarded.
-     */
-    private boolean isSafeToForget(IgniteInternalTx tx) {
-        Map.Entry<GridCacheVersion, AtomicInt> e = startVerCnts.firstEntry();
-
-        if (e == null)
-            return true;
-
-        assert e.getValue().get() >= 0;
-
-        return tx.endVersion().compareTo(e.getKey()) <= 0;
-    }
-
-    /**
-     * Decrement start version count.
-     *
-     * @param tx Cache transaction.
-     */
-    private void decrementStartVersionCount(IgniteInternalTx tx) {
-        AtomicInt cnt = startVerCnts.get(tx.startVersion());
-
-        assert cnt != null : "Failed to find start version count for transaction [startVerCnts=" + startVerCnts +
-            ", tx=" + tx + ']';
-
-        assert cnt.get() > 0;
-
-        if (cnt.decrementAndGet() == 0)
-            if (startVerCnts.remove(tx.startVersion(), cnt))
-                if (log.isDebugEnabled())
-                    log.debug("Removed start version for transaction: " + tx);
-    }
-
-    /**
      * @param tx Transaction.
      */
     private void removeObsolete(IgniteInternalTx tx) {
@@ -1237,6 +992,17 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
     }
 
     /**
+     * @param tx Transaction.
+     * @return {@code True} if transaction read entries should be unlocked.
+     */
+    private boolean unlockReadEntries(IgniteInternalTx tx) {
+        if (tx.pessimistic())
+            return !tx.readCommitted();
+        else
+            return tx.serializable();
+    }
+
+    /**
      * Commits a transaction.
      *
      * @param tx Transaction to commit.
@@ -1290,8 +1056,8 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             // 4. Unlock write resources.
             unlockMultiple(tx, tx.writeEntries());
 
-            // 5. For pessimistic transaction, unlock read resources if required.
-            if (tx.pessimistic() && !tx.readCommitted())
+            // 5. Unlock read resources if required.
+            if (unlockReadEntries(tx))
                 unlockMultiple(tx, tx.readEntries());
 
             // 6. Notify evictions.
@@ -1303,25 +1069,16 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             // 8. Assign transaction number at the end of transaction.
             tx.endVersion(cctx.versions().next(tx.topologyVersion()));
 
-            // 9. Clean start transaction number for this transaction.
-            if (cctx.txConfig().isTxSerializableEnabled())
-                decrementStartVersionCount(tx);
-
-            // 10. Add to committed queue only if it is possible
-            //    that this transaction can affect other ones.
-            if (cctx.txConfig().isTxSerializableEnabled() && tx.enforceSerializable() && !isSafeToForget(tx))
-                committedQ.add(tx);
-
-            // 11. Remove from per-thread storage.
+            // 9. Remove from per-thread storage.
             clearThreadMap(tx);
 
-            // 12. Unregister explicit locks.
+            // 10. Unregister explicit locks.
             if (!tx.alternateVersions().isEmpty()) {
                 for (GridCacheVersion ver : tx.alternateVersions())
                     idMap.remove(ver);
             }
 
-            // 13. Remove Near-2-DHT mappings.
+            // 11. Remove Near-2-DHT mappings.
             if (tx instanceof GridCacheMappedVersion) {
                 GridCacheVersion mapped = ((GridCacheMappedVersion)tx).mappedVersion();
 
@@ -1329,10 +1086,10 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
                     mappedVers.remove(mapped);
             }
 
-            // 14. Clear context.
+            // 12. Clear context.
             resetContext();
 
-            // 15. Update metrics.
+            // 14. Update metrics.
             if (!tx.dht() && tx.local()) {
                 if (!tx.system())
                     cctx.txMetrics().onTxCommit();
@@ -1378,8 +1135,8 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             // 2. Unlock write resources.
             unlockMultiple(tx, tx.writeEntries());
 
-            // 3. For pessimistic transaction, unlock read resources if required.
-            if (tx.pessimistic() && !tx.readCommitted())
+            // 3. Unlock read resources if required.
+            if (unlockReadEntries(tx))
                 unlockMultiple(tx, tx.readEntries());
 
             // 4. Notify evictions.
@@ -1388,26 +1145,22 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             // 5. Remove obsolete entries.
             removeObsolete(tx);
 
-            // 6. Clean start transaction number for this transaction.
-            if (cctx.txConfig().isTxSerializableEnabled())
-                decrementStartVersionCount(tx);
-
-            // 7. Remove from per-thread storage.
+            // 6. Remove from per-thread storage.
             clearThreadMap(tx);
 
-            // 8. Unregister explicit locks.
+            // 7. Unregister explicit locks.
             if (!tx.alternateVersions().isEmpty())
                 for (GridCacheVersion ver : tx.alternateVersions())
                     idMap.remove(ver);
 
-            // 9. Remove Near-2-DHT mappings.
+            // 8. Remove Near-2-DHT mappings.
             if (tx instanceof GridCacheMappedVersion)
                 mappedVers.remove(((GridCacheMappedVersion)tx).mappedVersion());
 
-            // 10. Clear context.
+            // 9. Clear context.
             resetContext();
 
-            // 11. Update metrics.
+            // 10. Update metrics.
             if (!tx.dht() && tx.local()) {
                 if (!tx.system())
                     cctx.txMetrics().onTxRollback();
@@ -1445,30 +1198,26 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
             // 1. Unlock write resources.
             unlockMultiple(tx, tx.writeEntries());
 
-            // 2. For pessimistic transaction, unlock read resources if required.
-            if (tx.pessimistic() && !tx.readCommitted())
+            // 2. Unlock read resources if required.
+            if (unlockReadEntries(tx))
                 unlockMultiple(tx, tx.readEntries());
 
             // 3. Notify evictions.
             notifyEvitions(tx);
 
-            // 4. Clean start transaction number for this transaction.
-            if (cctx.txConfig().isTxSerializableEnabled())
-                decrementStartVersionCount(tx);
-
-            // 5. Remove from per-thread storage.
+            // 4. Remove from per-thread storage.
             clearThreadMap(tx);
 
-            // 6. Unregister explicit locks.
+            // 5. Unregister explicit locks.
             if (!tx.alternateVersions().isEmpty())
                 for (GridCacheVersion ver : tx.alternateVersions())
                     idMap.remove(ver);
 
-            // 7. Remove Near-2-DHT mappings.
+            // 6. Remove Near-2-DHT mappings.
             if (tx instanceof GridCacheMappedVersion)
                 mappedVers.remove(((GridCacheMappedVersion)tx).mappedVersion());
 
-            // 8. Clear context.
+            // 7. Clear context.
             resetContext();
 
             if (log.isDebugEnabled())
@@ -1635,6 +1384,8 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
         // we wait for the lock.
         long timeout = tx.timeout() == 0 ? 0 : remainingTime;
 
+        GridCacheVersion serOrder = (tx.serializable() && tx.optimistic()) ? tx.nearXidVersion() : null;
+
         for (IgniteTxEntry txEntry1 : entries) {
             // Check if this entry was prepared before.
             if (!txEntry1.markPrepared() || txEntry1.explicitVersion() != null)
@@ -1649,7 +1400,11 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
                     assert !entry1.detached() : "Expected non-detached entry for near transaction " +
                         "[locNodeId=" + cctx.localNodeId() + ", entry=" + entry1 + ']';
 
-                    if (!entry1.tmLock(tx, timeout)) {
+                    GridCacheVersion serReadVer = txEntry1.serializableReadVersion();
+
+                    assert serReadVer == null || (tx.optimistic() && tx.serializable()) : txEntry1;
+
+                    if (!entry1.tmLock(tx, timeout, serOrder, serReadVer)) {
                         // Unlock locks locked so far.
                         for (IgniteTxEntry txEntry2 : entries) {
                             if (txEntry2 == txEntry1)

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java
index 36f1c36..68d03cd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/version/GridCacheVersionManager.java
@@ -53,9 +53,6 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
     /** Last version. */
     private volatile GridCacheVersion last;
 
-    /** Serializable transaction flag. */
-    private boolean txSerEnabled;
-
     /** Data center ID. */
     @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
     private byte dataCenterId;
@@ -64,6 +61,9 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
     private long gridStartTime;
 
     /** */
+    private GridCacheVersion ISOLATED_STREAMER_VER;
+
+    /** */
     private final GridLocalEventListener discoLsnr = new GridLocalEventListener() {
         @Override public void onEvent(Event evt) {
             assert evt.type() == EVT_NODE_METRICS_UPDATED;
@@ -79,8 +79,6 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
 
     /** {@inheritDoc} */
     @Override public void start0() throws IgniteCheckedException {
-        txSerEnabled = cctx.gridConfig().getTransactionConfiguration().isTxSerializableEnabled();
-
         last = new GridCacheVersion(0, 0, order.get(), 0, dataCenterId);
 
         cctx.gridEvents().addLocalEventListener(discoLsnr, EVT_NODE_METRICS_UPDATED);
@@ -154,6 +152,27 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
     }
 
     /**
+     * Version for entries loaded with isolated streamer, should be less than any version generated
+     * for entries update.
+     *
+     * @return Version for entries loaded with isolated streamer.
+     */
+    public GridCacheVersion isolatedStreamerVersion() {
+        if (ISOLATED_STREAMER_VER == null) {
+            long topVer = 1;
+
+            if (gridStartTime == 0)
+                gridStartTime = cctx.kernalContext().discovery().gridStartTime();
+
+            topVer += (gridStartTime - TOP_VER_BASE_TIME) / 1000;
+
+            ISOLATED_STREAMER_VER = new GridCacheVersion((int)topVer, 0, 0, 1, dataCenterId);
+        }
+
+        return ISOLATED_STREAMER_VER;
+    }
+
+    /**
      * @return Next version based on current topology.
      */
     public GridCacheVersion next() {
@@ -235,36 +254,18 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
 
         int locNodeOrder = (int)cctx.localNode().order();
 
-        if (txSerEnabled) {
-            synchronized (this) {
-                long ord = forLoad ? loadOrder.incrementAndGet() : order.incrementAndGet();
-
-                GridCacheVersion next = new GridCacheVersion(
-                    (int)topVer,
-                    globalTime,
-                    ord,
-                    locNodeOrder,
-                    dataCenterId);
-
-                last = next;
+        long ord = forLoad ? loadOrder.incrementAndGet() : order.incrementAndGet();
 
-                return next;
-            }
-        }
-        else {
-            long ord = forLoad ? loadOrder.incrementAndGet() : order.incrementAndGet();
-
-            GridCacheVersion next = new GridCacheVersion(
-                (int)topVer,
-                globalTime,
-                ord,
-                locNodeOrder,
-                dataCenterId);
+        GridCacheVersion next = new GridCacheVersion(
+            (int)topVer,
+            globalTime,
+            ord,
+            locNodeOrder,
+            dataCenterId);
 
-            last = next;
+        last = next;
 
-            return next;
-        }
+        return next;
     }
 
     /**
@@ -273,12 +274,6 @@ public class GridCacheVersionManager extends GridCacheSharedManagerAdapter {
      * @return Last generated version.
      */
     public GridCacheVersion last() {
-        if (txSerEnabled) {
-            synchronized (this) {
-                return last;
-            }
-        }
-        else
-            return last;
+        return last;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
index ab2a6e8..2190bf6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
@@ -1556,7 +1556,7 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
 
             AffinityTopologyVersion topVer = cctx.affinity().affinityTopologyVersion();
 
-            GridCacheVersion ver = cctx.versions().next(topVer);
+            GridCacheVersion ver = cctx.versions().isolatedStreamerVersion();
 
             long ttl = CU.TTL_ETERNAL;
             long expiryTime = CU.EXPIRE_TIME_ETERNAL;

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java b/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
index a6e960d..6c4e894 100644
--- a/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
+++ b/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
@@ -54,7 +54,7 @@ import org.apache.ignite.lang.IgniteUuid;
  *  Read access with this level happens the same way as with {@link TransactionIsolation#REPEATABLE_READ} level.
  *  However, in {@link TransactionConcurrency#OPTIMISTIC} mode, if some transactions cannot be serially isolated
  *  from each other, then one winner will be picked and the other transactions in conflict will result in
- * {@link org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException} being thrown.
+ * {@link TransactionOptimisticException} being thrown.
  * </li>
  * </ul>
  * <p>

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java b/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java
index d7671f0..c3be3c5 100644
--- a/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java
+++ b/modules/core/src/main/java/org/apache/ignite/transactions/TransactionIsolation.java
@@ -42,8 +42,7 @@ public enum TransactionIsolation {
      * @param ord Ordinal value.
      * @return Enumerated value or {@code null} if ordinal out of range.
      */
-    @Nullable
-    public static TransactionIsolation fromOrdinal(int ord) {
+    @Nullable public static TransactionIsolation fromOrdinal(int ord) {
         return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheNearReaderUpdateTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheNearReaderUpdateTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheNearReaderUpdateTest.java
new file mode 100644
index 0000000..c2f9fab
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheNearReaderUpdateTest.java
@@ -0,0 +1,388 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.cache.Cache;
+import javax.cache.configuration.Factory;
+import javax.cache.integration.CacheLoaderException;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.store.CacheStore;
+import org.apache.ignite.cache.store.CacheStoreAdapter;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.util.typedef.G;
+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.spi.swapspace.inmemory.GridTestSwapSpaceSpi;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.apache.ignite.transactions.TransactionOptimisticException;
+import org.jsr166.ConcurrentHashMap8;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ *
+ */
+public class CacheNearReaderUpdateTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private boolean client;
+
+    /** */
+    private static final int SRVS = 4;
+
+    /** */
+    private static final int CLIENTS = 3;
+
+    /** */
+    private static Map<Integer, Integer> storeMap = new ConcurrentHashMap8<>();
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setPeerClassLoadingEnabled(false);
+
+        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER);
+
+        cfg.setClientMode(client);
+
+        cfg.setSwapSpaceSpi(new GridTestSwapSpaceSpi());
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        startGridsMultiThreaded(SRVS);
+
+        client = true;
+
+        startGridsMultiThreaded(SRVS, CLIENTS);
+
+        client = false;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        super.afterTestsStopped();
+
+        stopAllGrids();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long getTestTimeout() {
+        return 10 * 60_000;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testGetUpdateMultithreaded() throws Exception {
+        List<CacheConfiguration<Integer, Integer>> cfgs = new ArrayList<>();
+
+        cfgs.add(cacheConfiguration(PARTITIONED, FULL_SYNC, 0, false, false));
+        cfgs.add(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false));
+        cfgs.add(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, true));
+        cfgs.add(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, true, false));
+
+        {
+            CacheConfiguration<Integer, Integer> ccfg = cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false);
+
+            GridTestUtils.setMemoryMode(null, ccfg, GridTestUtils.TestMemoryMode.OFFHEAP_TIERED, 0, 0);
+
+            cfgs.add(ccfg);
+        }
+
+        final List<Ignite> putNodes = new ArrayList<>();
+
+        for (int i = 0; i < SRVS + CLIENTS - 1; i++)
+            putNodes.add(ignite(i));
+
+        final List<Ignite> getNodes = new ArrayList<>();
+
+        getNodes.add(ignite(SRVS + CLIENTS - 1));
+        getNodes.add(ignite(0));
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cfgs) {
+            logCacheInfo(ccfg);
+
+            getUpdateMultithreaded(ccfg, putNodes, getNodes, null, null);
+
+            if (ccfg.getAtomicityMode() == TRANSACTIONAL) {
+                getUpdateMultithreaded(ccfg, putNodes, getNodes, PESSIMISTIC,  REPEATABLE_READ);
+
+                getUpdateMultithreaded(ccfg, putNodes, getNodes, OPTIMISTIC,  REPEATABLE_READ);
+
+                getUpdateMultithreaded(ccfg, putNodes, getNodes, OPTIMISTIC,  SERIALIZABLE);
+            }
+        }
+    }
+
+    /**
+     * @param ccfg Cache configuration.
+     * @param putNodes Nodes executing updates.
+     * @param getNodes Nodes executing gets.
+     * @param concurrency Transaction concurrency.
+     * @param isolation Transaction isolation.
+     * @throws Exception If failed.
+     */
+    private void getUpdateMultithreaded(CacheConfiguration<Integer, Integer> ccfg,
+        final List<Ignite> putNodes,
+        final List<Ignite> getNodes,
+        final TransactionConcurrency concurrency,
+        final TransactionIsolation isolation) throws Exception {
+        log.info("Execute updates [concurrency=" + concurrency + ", isolation=" + isolation + ']');
+
+        final Ignite ignite0 = ignite(0);
+
+        final String cacheName = ignite0.createCache(ccfg).getName();
+
+        try {
+            for (int i = 0; i < 5; i++) {
+                final Integer key = i;
+
+                final AtomicInteger putThreadIdx = new AtomicInteger();
+                final AtomicInteger getThreadIdx = new AtomicInteger();
+
+                final int PUT_THREADS = 20;
+                final int GET_THREAD = 20;
+
+                final CyclicBarrier barrier = new CyclicBarrier(PUT_THREADS + GET_THREAD);
+
+                final IgniteInternalFuture<?> updateFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
+                    @Override public Void call() throws Exception {
+                        int idx = putThreadIdx.getAndIncrement() % putNodes.size();
+
+                        Ignite ignite = putNodes.get(idx);
+
+                        IgniteCache<Integer, Integer> cache = ignite.cache(cacheName);
+
+                        IgniteTransactions txs = ignite.transactions();
+
+                        Thread.currentThread().setName("update-thread-" + ignite.name());
+
+                        barrier.await();
+
+                        for (int i = 0; i < 100; i++) {
+                            ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+                            if (concurrency != null) {
+                                try (Transaction tx = txs.txStart(concurrency, isolation)) {
+                                    cache.put(key, rnd.nextInt());
+
+                                    tx.commit();
+                                }
+                                catch (TransactionOptimisticException ignore) {
+                                    assertEquals(concurrency, OPTIMISTIC);
+                                    assertEquals(isolation, SERIALIZABLE);
+                                }
+                            }
+                            else
+                                cache.put(key, rnd.nextInt());
+                        }
+
+                        return null;
+                    }
+                }, PUT_THREADS, "update-thread");
+
+                IgniteInternalFuture<?> getFut = GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
+                    @Override public Void call() throws Exception {
+                        int idx = getThreadIdx.getAndIncrement() % getNodes.size();
+
+                        Ignite ignite = getNodes.get(idx);
+
+                        IgniteCache<Integer, Integer> cache;
+
+                        if (ignite.configuration().isClientMode())
+                            cache = ignite.createNearCache(cacheName, new NearCacheConfiguration<Integer, Integer>());
+                        else
+                            cache = ignite.cache(cacheName);
+
+                        Thread.currentThread().setName("get-thread-" + ignite.name());
+
+                        barrier.await();
+
+                        while (!updateFut.isDone())
+                            cache.get(key);
+
+                        return null;
+                    }
+                }, GET_THREAD, "get-thread");
+
+                updateFut.get();
+                getFut.get();
+
+                Integer val = (Integer)ignite0.cache(cacheName).get(key);
+
+                log.info("Iteration [iter=" + i + ", val=" + val + ']');
+
+                for (Ignite getNode : getNodes) {
+                    IgniteCache<Integer, Integer> cache = getNode.cache(cacheName);
+
+                    if (getNode.configuration().isClientMode() ||
+                        cache.getConfiguration(CacheConfiguration.class).getNearConfiguration() != null)
+                    assertNotNull(getNode.cache(cacheName).localPeek(key));
+                }
+
+                checkValue(key, val, cacheName);
+
+                for (int n = 0; n < SRVS + CLIENTS; n++) {
+                    val = n;
+
+                    ignite(n).cache(cacheName).put(key, val);
+
+                    checkValue(key, val, cacheName);
+                }
+            }
+        }
+        finally {
+            destroyCache(ignite0, cacheName);
+        }
+    }
+
+    /**
+     * @param key Key.
+     * @param expVal Expected value.
+     * @param cacheName Cache name.
+     */
+    private void checkValue(Object key, Object expVal, String cacheName) {
+        for (int i = 0; i < SRVS + CLIENTS; i++) {
+            IgniteCache<Object, Object> cache = ignite(i).cache(cacheName);
+
+            assertEquals(expVal, cache.get(key));
+        }
+    }
+
+    /**
+     * @param ccfg Cache configuration.
+     */
+    private void logCacheInfo(CacheConfiguration<?, ?> ccfg) {
+        log.info("Test cache [mode=" + ccfg.getCacheMode() +
+            ", sync=" + ccfg.getWriteSynchronizationMode() +
+            ", backups=" + ccfg.getBackups() +
+            ", memMode=" + ccfg.getMemoryMode() +
+            ", near=" + (ccfg.getNearConfiguration() != null) +
+            ", store=" + ccfg.isWriteThrough() +
+            ", evictPlc=" + (ccfg.getEvictionPolicy() != null) +
+            ", swap=" + ccfg.isSwapEnabled()  +
+            ", maxOffheap=" + ccfg.getOffHeapMaxMemory()  +
+            ']');
+    }
+
+    /**
+     * @param ignite Node.
+     * @param cacheName Cache name.
+     */
+    private void destroyCache(Ignite ignite, String cacheName) {
+        storeMap.clear();
+
+        ignite.destroyCache(cacheName);
+
+        for (Ignite ignite0 : G.allGrids()) {
+            GridTestSwapSpaceSpi spi = (GridTestSwapSpaceSpi)ignite0.configuration().getSwapSpaceSpi();
+
+            spi.clearAll();
+        }
+    }
+
+    /**
+     * @param cacheMode Cache mode.
+     * @param syncMode Write synchronization mode.
+     * @param backups Number of backups.
+     * @param storeEnabled If {@code true} adds cache store.
+     * @param nearCache If {@code true} near cache is enabled.
+     * @return Cache configuration.
+     */
+    private CacheConfiguration<Integer, Integer> cacheConfiguration(
+        CacheMode cacheMode,
+        CacheWriteSynchronizationMode syncMode,
+        int backups,
+        boolean storeEnabled,
+        boolean nearCache) {
+        CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>();
+
+        ccfg.setCacheMode(cacheMode);
+        ccfg.setAtomicityMode(TRANSACTIONAL);
+        ccfg.setWriteSynchronizationMode(syncMode);
+
+        if (cacheMode == PARTITIONED)
+            ccfg.setBackups(backups);
+
+        if (storeEnabled) {
+            ccfg.setCacheStoreFactory(new TestStoreFactory());
+            ccfg.setWriteThrough(true);
+            ccfg.setReadThrough(true);
+        }
+
+        if (nearCache)
+            ccfg.setNearConfiguration(new NearCacheConfiguration<Integer, Integer>());
+
+        return ccfg;
+    }
+
+    /**
+     *
+     */
+    private static class TestStoreFactory implements Factory<CacheStore<Integer, Integer>> {
+        /** {@inheritDoc} */
+        @Override public CacheStore<Integer, Integer> create() {
+            return new CacheStoreAdapter<Integer, Integer>() {
+                @Override public Integer load(Integer key) throws CacheLoaderException {
+                    return storeMap.get(key);
+                }
+
+                @Override public void write(Cache.Entry<? extends Integer, ? extends Integer> entry) {
+                    storeMap.put(entry.getKey(), entry.getValue());
+                }
+
+                @Override public void delete(Object key) {
+                    storeMap.remove(key);
+                }
+            };
+        }
+    }
+}


[22/31] ignite git commit: ignite-1607 Implemented deadlock-free optimistic serializable tx mode

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
index cedb693..2577d93 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CrossCacheTxRandomOperationsTest.java
@@ -52,6 +52,7 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.PRIMARY_SYNC
 import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
 import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
 import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
 
 /**
  *
@@ -190,6 +191,11 @@ public class CrossCacheTxRandomOperationsTest extends GridCommonAbstractTest {
 
             txOperations(OPTIMISTIC, REPEATABLE_READ, crossCacheTx, false);
             txOperations(OPTIMISTIC, REPEATABLE_READ, crossCacheTx, true);
+
+            if (writeSync == FULL_SYNC) {
+                txOperations(OPTIMISTIC, SERIALIZABLE, crossCacheTx, false);
+                txOperations(OPTIMISTIC, SERIALIZABLE, crossCacheTx, true);
+            }
         }
         finally {
             ignite.destroyCache(CACHE1);

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java
index f4813ff..da54d15 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFailoverSelfTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.cache;
 
+import java.util.Collections;
 import java.util.concurrent.atomic.AtomicReference;
 import javax.cache.CacheException;
 import org.apache.ignite.Ignite;
@@ -330,14 +331,21 @@ public abstract class GridCacheAbstractFailoverSelfTest extends GridCacheAbstrac
      * @throws IgniteCheckedException If failed.
      */
     private void remove(Ignite ignite, IgniteCache<String, Integer> cache, final int cnt,
-        TransactionConcurrency concurrency, TransactionIsolation isolation) throws Exception {
+        TransactionConcurrency concurrency, final TransactionIsolation isolation) throws Exception {
         try {
             info("Removing values form cache [0," + cnt + ')');
 
             CU.inTx(ignite, cache, concurrency, isolation, new CIX1<IgniteCache<String, Integer>>() {
                 @Override public void applyx(IgniteCache<String, Integer> cache) {
-                    for (int i = 0; i < cnt; i++)
-                        cache.remove("key" + i);
+                    for (int i = 0; i < cnt; i++) {
+                        String key = "key" + i;
+
+                        // Use removeAll for serializable tx to avoid version check.
+                        if (isolation == TransactionIsolation.SERIALIZABLE)
+                            cache.removeAll(Collections.singleton(key));
+                        else
+                            cache.remove(key);
+                    }
                 }
             });
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 ec3ea0c..a6b5535 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
@@ -3692,7 +3692,7 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract
         if (txShouldBeUsed()) {
             try (Transaction tx = transactions().txStart(OPTIMISTIC, READ_COMMITTED)) {
                 // Remove missing key.
-                assertTrue(jcache().remove(UUID.randomUUID().toString()));
+                assertFalse(jcache().remove(UUID.randomUUID().toString()));
 
                 tx.commit();
             }
@@ -3708,7 +3708,7 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract
         if (txShouldBeUsed()) {
             try (Transaction tx = transactions().txStart(OPTIMISTIC, READ_COMMITTED)) {
                 // Remove missing key.
-                assertTrue(jcache().remove(UUID.randomUUID().toString()));
+                assertFalse(jcache().remove(UUID.randomUUID().toString()));
 
                 tx.setRollbackOnly();
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
index 122910e..5044516 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractRemoveFailureTest.java
@@ -30,6 +30,8 @@ import java.util.concurrent.atomic.AtomicReference;
 import javax.cache.CacheException;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteTransactions;
 import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
@@ -37,9 +39,11 @@ import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.util.lang.GridTuple;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
@@ -48,11 +52,18 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
 import org.jsr166.ConcurrentHashMap8;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE;
 import static org.apache.ignite.cache.CacheMode.PARTITIONED;
 import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
 
 /**
  * Tests that removes are not lost when topology changes.
@@ -155,29 +166,54 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
      * @throws Exception If failed.
      */
     public void testPutAndRemove() throws Exception {
-        putAndRemove(DUR, GridTestUtils.TestMemoryMode.HEAP);
+        putAndRemove(DUR, null, null, GridTestUtils.TestMemoryMode.HEAP);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPutAndRemovePessimisticTx() throws Exception {
+        if (atomicityMode() != CacheAtomicityMode.TRANSACTIONAL)
+            return;
+
+        putAndRemove(30_000, PESSIMISTIC, REPEATABLE_READ, GridTestUtils.TestMemoryMode.HEAP);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPutAndRemoveOptimisticSerializableTx() throws Exception {
+        if (atomicityMode() != CacheAtomicityMode.TRANSACTIONAL)
+            return;
+
+        putAndRemove(30_000, OPTIMISTIC, SERIALIZABLE, GridTestUtils.TestMemoryMode.HEAP);
     }
 
     /**
      * @throws Exception If failed.
      */
     public void testPutAndRemoveOffheapEvict() throws Exception {
-        putAndRemove(30_000, GridTestUtils.TestMemoryMode.OFFHEAP_EVICT);
+        putAndRemove(30_000, null, null, GridTestUtils.TestMemoryMode.OFFHEAP_EVICT);
     }
 
     /**
      * @throws Exception If failed.
      */
     public void testPutAndRemoveOffheapEvictSwap() throws Exception {
-        putAndRemove(30_000, GridTestUtils.TestMemoryMode.OFFHEAP_EVICT_SWAP);
+        putAndRemove(30_000, null, null, GridTestUtils.TestMemoryMode.OFFHEAP_EVICT_SWAP);
     }
 
     /**
      * @param duration Test duration.
+     * @param txConcurrency Transaction concurrency if test explicit transaction.
+     * @param txIsolation Transaction isolation if test explicit transaction.
      * @param memMode Memory mode.
      * @throws Exception If failed.
      */
-    private void putAndRemove(long duration, GridTestUtils.TestMemoryMode memMode) throws Exception {
+    private void putAndRemove(long duration,
+        final TransactionConcurrency txConcurrency,
+        final TransactionIsolation txIsolation,
+        GridTestUtils.TestMemoryMode memMode) throws Exception {
         assertEquals(testClientNode(), (boolean) grid(0).configuration().isClientMode());
 
         grid(0).destroyCache(null);
@@ -216,6 +252,8 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
 
                 ThreadLocalRandom rnd = ThreadLocalRandom.current();
 
+                IgniteTransactions txs = sndCache0.unwrap(Ignite.class).transactions();
+
                 while (!stop.get()) {
                     for (int i = 0; i < 100; i++) {
                         int key = rnd.nextInt(KEYS_CNT);
@@ -225,14 +263,54 @@ public abstract class GridCacheAbstractRemoveFailureTest extends GridCommonAbstr
                         while (true) {
                             try {
                                 if (put) {
-                                    sndCache0.put(key, i);
+                                    boolean failed = false;
+
+                                    if (txConcurrency != null) {
+                                        try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) {
+                                            sndCache0.put(key, i);
+
+                                            tx.commit();
+                                        }
+                                        catch (CacheException | IgniteException e) {
+                                            if (!X.hasCause(e, ClusterTopologyCheckedException.class)) {
+                                                log.error("Unexpected error: " + e);
+
+                                                throw e;
+                                            }
 
-                                    expVals.put(key, F.t(i));
+                                            failed = true;
+                                        }
+                                    }
+                                    else
+                                        sndCache0.put(key, i);
+
+                                    if (!failed)
+                                        expVals.put(key, F.t(i));
                                 }
                                 else {
-                                    sndCache0.remove(key);
+                                    boolean failed = false;
+
+                                    if (txConcurrency != null) {
+                                        try (Transaction tx = txs.txStart(txConcurrency, txIsolation)) {
+                                            sndCache0.remove(key);
+
+                                            tx.commit();
+                                        }
+                                        catch (CacheException | IgniteException e) {
+                                            if (!X.hasCause(e, ClusterTopologyCheckedException.class)) {
+                                                log.error("Unexpected error: " + e);
+
+                                                throw e;
+                                            }
+
+                                            failed = true;
+                                        }
+                                    }
+                                    else
+                                        sndCache0.remove(key);
 
-                                    expVals.put(key, F.<Integer>t(null));
+                                    if (!failed)
+                                        expVals.put(key, F.<Integer>t(null));
                                 }
 
                                 break;

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java
index 67bc08c..1ef77f2 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConcurrentTxMultiNodeTest.java
@@ -162,9 +162,6 @@ public class GridCacheConcurrentTxMultiNodeTest extends GridCommonAbstractTest {
 
         c.setPeerClassLoadingEnabled(false);
 
-        // Enable tracing.
-//        Logger.getLogger("org.apache.ignite.kernal.processors.cache.GridCacheDgcManager.trace").setLevel(Level.DEBUG);
-
         return c;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 084bc75..234f362 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
@@ -88,7 +88,8 @@ public class GridCacheMvccFlagsTest extends GridCommonAbstractTest {
             true,
             true,
             true,
-            true
+            true,
+            null
         );
 
         c.setOwner();
@@ -128,7 +129,8 @@ public class GridCacheMvccFlagsTest extends GridCommonAbstractTest {
             false,
             false,
             false,
-            false
+            false,
+            null
         );
 
         short flags = c.flags();

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 0af7183..1b97663 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
@@ -595,6 +595,170 @@ public class GridCacheMvccPartitionedSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * @throws Exception If failed.
+     */
+    public void testSerializableLocks() throws Exception {
+        checkSerializableAdd(false);
+
+        checkSerializableAdd(true);
+
+        checkNonSerializableConflict();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void checkNonSerializableConflict() throws Exception {
+        GridCacheAdapter<String, String> cache = grid.internalCache();
+
+        UUID nodeId = UUID.randomUUID();
+
+        GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
+
+        GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
+
+        GridCacheMvccCandidate cand1 = mvcc.addLocal(e,
+            nodeId,
+            null,
+            1,
+            version(1),
+            0,
+            null,
+            false,
+            true,
+            false,
+            true
+        );
+
+        assertNotNull(cand1);
+
+        GridCacheMvccCandidate cand2 = mvcc.addLocal(e,
+            nodeId,
+            null,
+            1,
+            version(2),
+            0,
+            new GridCacheVersion(0, 0, 30, 1),
+            false,
+            true,
+            false,
+            true
+        );
+
+        assertNull(cand2);
+    }
+
+    /**
+     * @param incVer If {@code true} lock version is incremented.
+     * @throws Exception If failed.
+     */
+    private void checkSerializableAdd(boolean incVer) throws Exception {
+        GridCacheAdapter<String, String> cache = grid.internalCache();
+
+        UUID nodeId = UUID.randomUUID();
+
+        GridCacheMvcc mvcc = new GridCacheMvcc(cache.context());
+
+        GridCacheTestEntryEx e = new GridCacheTestEntryEx(cache.context(), "1");
+
+        GridCacheVersion serOrder1 = new GridCacheVersion(0, 0, 10, 1);
+        GridCacheVersion serOrder2 = new GridCacheVersion(0, 0, 20, 1);
+        GridCacheVersion serOrder3 = new GridCacheVersion(0, 0, 15, 1);
+        GridCacheVersion serOrder4 = new GridCacheVersion(0, 0, 30, 1);
+
+        GridCacheVersion ver1 = incVer ? version(1) : version(4);
+        GridCacheVersion ver2 = incVer ? version(2) : version(3);
+        GridCacheVersion ver3 = incVer ? version(3) : version(2);
+        GridCacheVersion ver4 = incVer ? version(4) : version(1);
+
+        GridCacheMvccCandidate cand1 = mvcc.addLocal(e,
+            nodeId,
+            null,
+            1,
+            ver1,
+            0,
+            serOrder1,
+            false,
+            true,
+            false,
+            true
+            );
+
+        assertNotNull(cand1);
+
+        GridCacheMvccCandidate cand2 = mvcc.addLocal(e,
+            nodeId,
+            null,
+            2,
+            ver2,
+            0,
+            serOrder2,
+            false,
+            true,
+            false,
+            true
+        );
+
+        assertNotNull(cand2);
+
+        GridCacheMvccCandidate cand3 = mvcc.addLocal(e,
+            nodeId,
+            null,
+            3,
+            ver3,
+            0,
+            serOrder3,
+            false,
+            true,
+            false,
+            true
+        );
+
+        assertNull(cand3);
+
+        GridCacheMvccCandidate cand4 = mvcc.addLocal(e,
+            nodeId,
+            null,
+            4,
+            ver4,
+            0,
+            serOrder4,
+            false,
+            true,
+            false,
+            true
+        );
+
+        assertNotNull(cand4);
+
+        GridCacheMvccCandidate owner = mvcc.recheck();
+
+        assertNull(owner);
+
+        cand2.setReady();
+
+        owner = mvcc.recheck();
+
+        assertNull(owner);
+
+        cand1.setReady();
+
+        owner = mvcc.recheck();
+
+        assertSame(cand1, owner);
+
+        owner = mvcc.recheck();
+
+        assertSame(cand1, owner);
+
+        mvcc.remove(cand1.version());
+
+        owner = mvcc.recheck();
+
+        assertSame(cand2, owner);
+    }
+
+    /**
      * Gets version based on order.
      *
      * @param order Order.

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java
index cdf8eca..59f9a9d 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheMvccSelfTest.java
@@ -101,7 +101,8 @@ public class GridCacheMvccSelfTest extends GridCommonAbstractTest {
             true,
             false,
             false,
-            false
+            false,
+            null
         );
 
         Marshaller marshaller = getTestResources().getMarshaller();

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
index 1fef4d5..abb2767 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
@@ -33,6 +33,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersionedEnt
 import org.apache.ignite.internal.processors.dr.GridDrType;
 import org.apache.ignite.internal.util.lang.GridMetadataAwareAdapter;
 import org.apache.ignite.internal.util.lang.GridTuple3;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -441,6 +442,22 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
     }
 
     /** @inheritDoc */
+    @Nullable @Override public T2<CacheObject, GridCacheVersion> innerGetVersioned(
+        IgniteInternalTx tx,
+        boolean readSwap,
+        boolean unmarshal,
+        boolean updateMetrics,
+        boolean evt,
+        UUID subjId,
+        Object transformClo,
+        String taskName,
+        @Nullable IgniteCacheExpiryPolicy expiryPlc) {
+        assert false;
+
+        return null;
+    }
+
+    /** @inheritDoc */
     @Override public CacheObject innerReload() {
         return val;
     }
@@ -456,9 +473,14 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
         boolean evt,
         boolean metrics,
         AffinityTopologyVersion topVer,
-        CacheEntryPredicate[] filter, GridDrType drType,
-        long drExpireTime, @Nullable GridCacheVersion drVer, UUID subjId, String taskName) throws IgniteCheckedException,
-        GridCacheEntryRemovedException {
+        CacheEntryPredicate[] filter,
+        GridDrType drType,
+        long drExpireTime,
+        @Nullable GridCacheVersion drVer,
+        UUID subjId,
+        String taskName,
+        @Nullable GridCacheVersion dhtVer)
+        throws IgniteCheckedException, GridCacheEntryRemovedException {
         return new GridCacheUpdateTxResult(true, rawPut(val, ttl));
     }
 
@@ -528,8 +550,9 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
         GridDrType drType,
         @Nullable GridCacheVersion drVer,
         UUID subjId,
-        String taskName
-    ) throws IgniteCheckedException, GridCacheEntryRemovedException {
+        String taskName,
+        @Nullable GridCacheVersion dhtVer
+        ) throws IgniteCheckedException, GridCacheEntryRemovedException {
         obsoleteVer = ver;
 
         CacheObject old = val;
@@ -552,7 +575,10 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
     }
 
     /** @inheritDoc */
-    @Override public boolean tmLock(IgniteInternalTx tx, long timeout) {
+    @Override public boolean tmLock(IgniteInternalTx tx,
+        long timeout,
+        @Nullable GridCacheVersion serOrder,
+        GridCacheVersion serReadVer) {
         assert false; return false;
     }
 
@@ -613,6 +639,13 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
     }
 
     /** @inheritDoc */
+    @Override public boolean checkSerializableReadVersion(GridCacheVersion ver) {
+        assert false;
+
+        return false;
+    }
+
+    /** @inheritDoc */
     @Override public boolean initialValue(
         CacheObject val,
         GridCacheVersion ver,
@@ -640,8 +673,12 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter implements Gr
     }
 
     /** @inheritDoc */
-    @Override public boolean versionedValue(CacheObject val, GridCacheVersion curVer, GridCacheVersion newVer) {
-        assert false; return false;
+    @Override public GridCacheVersion versionedValue(CacheObject val,
+        GridCacheVersion curVer,
+        GridCacheVersion newVer) {
+        assert false;
+
+        return null;
     }
 
     /** @inheritDoc */

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java
index fcf46cf..dff0344 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxAbstractTest.java
@@ -175,9 +175,7 @@ abstract class IgniteTxAbstractTest extends GridCommonAbstractTest {
         for (int i = 0; i < iterations(); i++) {
             IgniteCache<Integer, String> cache = jcache(gridIdx);
 
-            Transaction tx = ignite(gridIdx).transactions().txStart(concurrency, isolation, 0, 0);
-
-            try {
+            try (Transaction tx = ignite(gridIdx).transactions().txStart(concurrency, isolation, 0, 0)) {
                 int prevKey = -1;
 
                 for (Integer key : getKeys()) {
@@ -236,46 +234,22 @@ abstract class IgniteTxAbstractTest extends GridCommonAbstractTest {
                     debug("Committed transaction [i=" + i + ", tx=" + tx + ']');
             }
             catch (TransactionOptimisticException e) {
-                if (concurrency != OPTIMISTIC || isolation != SERIALIZABLE) {
-                    error("Received invalid optimistic failure.", e);
+                if (!(concurrency == OPTIMISTIC && isolation == SERIALIZABLE)) {
+                    log.error("Unexpected error: " + e, e);
 
                     throw e;
                 }
-
-                if (isTestDebug())
-                    info("Optimistic transaction failure (will rollback) [i=" + i + ", msg=" + e.getMessage() +
-                        ", tx=" + tx.xid() + ']');
-
-                try {
-                    tx.rollback();
-                }
-                catch (IgniteException ex) {
-                    error("Failed to rollback optimistic failure: " + tx, ex);
-
-                    throw ex;
-                }
             }
-            catch (Exception e) {
-                error("Transaction failed (will rollback): " + tx, e);
-
-                tx.rollback();
+            catch (Throwable e) {
+                log.error("Unexpected error: " + e, e);
 
                 throw e;
             }
-            catch (Error e) {
-                error("Error when executing transaction (will rollback): " + tx, e);
-
-                tx.rollback();
+        }
 
-                throw e;
-            }
-            finally {
-                Transaction t = ignite(gridIdx).transactions().tx();
+        Transaction tx = ignite(gridIdx).transactions().tx();
 
-                assert t == null : "Thread should not have transaction upon completion ['t==tx'=" + (t == tx) +
-                    ", t=" + t + (t != tx ? "tx=" + tx : "tx=''") + ']';
-            }
-        }
+        assertNull("Thread should not have transaction upon completion", tx);
 
         if (printMemoryStats()) {
             if (cntr.getAndIncrement() % 100 == 0)

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java
index 9e14d30..f13ba8c 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteTxMultiThreadedAbstractTest.java
@@ -219,78 +219,98 @@ public abstract class IgniteTxMultiThreadedAbstractTest extends IgniteTxAbstract
      * @throws Exception If failed.
      */
     public void testOptimisticSerializableConsistency() throws Exception {
-        fail("https://issues.apache.org/jira/browse/IGNITE-582");
-
         final IgniteCache<Integer, Long> cache = grid(0).cache(null);
 
-        final int THREADS = 2;
+        final int THREADS = 3;
 
         final int ITERATIONS = 100;
 
-        final int key = 0;
+        for (int key0 = 100_000; key0 < 100_000 + 20; key0++) {
+            final int key = key0;
 
-        cache.put(key, 0L);
+            cache.put(key, 0L);
 
-        List<IgniteInternalFuture<Collection<Long>>> futs = new ArrayList<>(THREADS);
+            List<IgniteInternalFuture<Collection<Long>>> futs = new ArrayList<>(THREADS);
 
-        for (int i = 0; i < THREADS; i++) {
-            futs.add(GridTestUtils.runAsync(new Callable<Collection<Long>>() {
-                @Override public Collection<Long> call() throws Exception {
-                    Collection<Long> res = new ArrayList<>();
+            for (int i = 0; i < THREADS; i++) {
+                futs.add(GridTestUtils.runAsync(new Callable<Collection<Long>>() {
+                    @Override public Collection<Long> call() throws Exception {
+                        Collection<Long> res = new ArrayList<>();
 
-                    for (int i = 0; i < ITERATIONS; i++) {
-                        while (true) {
-                            try (Transaction tx = grid(0).transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
-                                long val = cache.get(key);
+                        for (int i = 0; i < ITERATIONS; i++) {
+                            while (true) {
+                                try (Transaction tx = grid(0).transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+                                    long val = cache.get(key);
 
-                                cache.put(key, val + 1);
+                                    cache.put(key, val + 1);
 
-                                tx.commit();
+                                    tx.commit();
 
-                                assertTrue(res.add(val + 1));
+                                    assertTrue(res.add(val + 1));
 
-                                break;
-                            }
-                            catch(TransactionOptimisticException e) {
-                                log.info("Got error, will retry: " + e);
+                                    break;
+                                }
+                                catch (TransactionOptimisticException e) {
+                                    // Retry.
+                                }
                             }
                         }
+
+                        return res;
                     }
+                }));
+            }
 
-                    return res;
-                }
-            }));
-        }
+            long total = 0;
 
-        List<Collection<Long>> cols = new ArrayList<>(THREADS);
+            List<Collection<Long>> cols = new ArrayList<>(THREADS);
 
-        for (IgniteInternalFuture<Collection<Long>> fut : futs) {
-            Collection<Long> col = fut.get();
+            for (IgniteInternalFuture<Collection<Long>> fut : futs) {
+                Collection<Long> col = fut.get();
 
-            assertEquals(ITERATIONS, col.size());
+                assertEquals(ITERATIONS, col.size());
 
-            cols.add(col);
-        }
+                total += col.size();
+
+                cols.add(col);
+            }
+
+            log.info("Cache value: " + cache.get(key));
 
-        Set<Long> duplicates = new HashSet<>();
+            Set<Long> duplicates = new HashSet<>();
 
-        for (Collection<Long> col1 : cols) {
-            for (Long val1 : col1) {
-                for (Collection<Long> col2 : cols) {
-                    if (col1 == col2)
-                        continue;
+            for (Collection<Long> col1 : cols) {
+                for (Long val1 : col1) {
+                    for (Collection<Long> col2 : cols) {
+                        if (col1 == col2)
+                            continue;
 
-                    for (Long val2 : col2) {
-                        if (val1.equals(val2)) {
-                            duplicates.add(val2);
+                        for (Long val2 : col2) {
+                            if (val1.equals(val2)) {
+                                duplicates.add(val2);
 
-                            break;
+                                break;
+                            }
                         }
                     }
                 }
             }
-        }
 
-        assertTrue("Found duplicated values: " + duplicates, duplicates.isEmpty());
+            assertTrue("Found duplicated values: " + duplicates, duplicates.isEmpty());
+
+            assertEquals((long)THREADS * ITERATIONS, total);
+
+            // Try to update one more time to make sure cache is in consistent state.
+            try (Transaction tx = grid(0).transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+                long val = cache.get(key);
+
+                cache.put(key, val);
+
+                tx.commit();
+            }
+
+            for (int i = 0; i < gridCount(); i++)
+                assertEquals(total, grid(i).cache(null).get(key));
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.java
new file mode 100644
index 0000000..ab9dc76
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed;
+
+import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedTxMultiThreadedSelfTest;
+
+/**
+ *
+ */
+public class GridCachePartitionedNearDisabledTxMultiThreadedSelfTest
+    extends GridCachePartitionedTxMultiThreadedSelfTest {
+    /** {@inheritDoc} */
+    @Override protected boolean nearEnabled() {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java
index b6e86f2..cb83798 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteCacheClientNodeChangingTopologyTest.java
@@ -80,6 +80,7 @@ import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.transactions.Transaction;
 import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
 import org.eclipse.jetty.util.ConcurrentHashSet;
 import org.jetbrains.annotations.Nullable;
 
@@ -93,6 +94,7 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
 import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
 import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
 
 /**
  *
@@ -803,6 +805,9 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
 
         TestCommunicationSpi spi = (TestCommunicationSpi)ignite3.configuration().getCommunicationSpi();
 
+        for (int i = 0; i < 100; i++)
+            primaryCache(i, null).put(i, -1);
+
         final Map<Integer, Integer> map = new HashMap<>();
 
         for (int i = 0; i < 100; i++)
@@ -866,6 +871,150 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
     /**
      * @throws Exception If failed.
      */
+    public void testOptimisticSerializableTx() throws Exception {
+        optimisticSerializableTx(null);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testOptimisticSerializableTxNearEnabled() throws Exception {
+        optimisticSerializableTx(new NearCacheConfiguration());
+    }
+
+    /**
+     * @param nearCfg Near cache configuration.
+     * @throws Exception If failed.
+     */
+    private void optimisticSerializableTx(NearCacheConfiguration nearCfg) throws Exception {
+        ccfg = new CacheConfiguration();
+
+        ccfg.setCacheMode(PARTITIONED);
+        ccfg.setBackups(1);
+        ccfg.setAtomicityMode(TRANSACTIONAL);
+        ccfg.setWriteSynchronizationMode(FULL_SYNC);
+        ccfg.setRebalanceMode(SYNC);
+        ccfg.setNearConfiguration(nearCfg);
+
+        IgniteEx ignite0 = startGrid(0);
+        IgniteEx ignite1 = startGrid(1);
+
+        client = true;
+
+        final Ignite ignite2 = startGrid(2);
+
+        assertTrue(ignite2.configuration().isClientMode());
+
+        final Map<Integer, Integer> map = new HashMap<>();
+
+        for (int i = 0; i < 100; i++)
+            map.put(i, i);
+
+        TestCommunicationSpi spi = (TestCommunicationSpi)ignite2.configuration().getCommunicationSpi();
+
+        spi.blockMessages(GridNearTxPrepareRequest.class, ignite0.localNode().id());
+        spi.blockMessages(GridNearTxPrepareRequest.class, ignite1.localNode().id());
+
+        spi.record(GridNearTxPrepareRequest.class);
+
+        final IgniteCache<Integer, Integer> cache = ignite2.cache(null);
+
+        IgniteInternalFuture<?> putFut = GridTestUtils.runAsync(new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                Thread.currentThread().setName("put-thread");
+
+                try (Transaction tx = ignite2.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    cache.putAll(map);
+
+                    tx.commit();
+                }
+
+                return null;
+            }
+        });
+
+        assertFalse(putFut.isDone());
+
+        client = false;
+
+        IgniteEx ignite3 = startGrid(3);
+
+        log.info("Stop block1.");
+
+        spi.stopBlock();
+
+        putFut.get();
+
+        spi.record(null);
+
+        checkData(map, null, cache, 4);
+
+        List<Object> msgs = spi.recordedMessages();
+
+        for (Object msg : msgs)
+            assertTrue(((GridNearTxPrepareRequest)msg).firstClientRequest());
+
+        assertEquals(5, msgs.size());
+
+        ignite3.close();
+
+        for (int i = 0; i < 100; i++)
+            map.put(i, i + 1);
+
+        spi.blockMessages(GridNearTxPrepareRequest.class, ignite0.localNode().id());
+        spi.blockMessages(GridNearTxPrepareRequest.class, ignite1.localNode().id());
+
+        spi.record(GridNearTxPrepareRequest.class);
+
+        putFut = GridTestUtils.runAsync(new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                Thread.currentThread().setName("put-thread");
+
+                try (Transaction tx = ignite2.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    for (Map.Entry<Integer, Integer> e : map.entrySet())
+                        cache.put(e.getKey(), e.getValue());
+
+                    tx.commit();
+                }
+
+                return null;
+            }
+        });
+
+        ignite3 = startGrid(3);
+
+        log.info("Stop block2.");
+
+        spi.stopBlock();
+
+        putFut.get();
+
+        spi.record(null);
+
+        msgs = spi.recordedMessages();
+
+        for (Object msg : msgs)
+            assertTrue(((GridNearTxPrepareRequest)msg).firstClientRequest());
+
+        assertEquals(5, msgs.size());
+
+        checkData(map, null, cache, 4);
+
+        for (int i = 0; i < 100; i++)
+            map.put(i, i + 2);
+
+        try (Transaction tx = ignite2.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+            cache.putAll(map);
+
+            tx.commit();
+        }
+
+        checkData(map, null, cache, 4);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testLock() throws Exception {
         lock(null);
     }
@@ -1428,6 +1577,13 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
     /**
      * @throws Exception If failed.
      */
+    public void testOptimisticSerializableTxPutAllMultinode() throws Exception {
+        multinode(null, TestType.OPTIMISTIC_SERIALIZABLE_TX);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testPessimisticTxPutAllMultinode() throws Exception {
         multinode(null, TestType.PESSIMISTIC_TX);
     }
@@ -1497,7 +1653,9 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
 
                     IgniteCache<Integer, Integer> cache = ignite.cache(null);
 
-                    boolean useTx = testType == TestType.OPTIMISTIC_TX || testType == TestType.PESSIMISTIC_TX;
+                    boolean useTx = testType == TestType.OPTIMISTIC_TX ||
+                        testType == TestType.OPTIMISTIC_SERIALIZABLE_TX ||
+                        testType == TestType.PESSIMISTIC_TX;
 
                     if (useTx || testType == TestType.LOCK) {
                         assertEquals(TRANSACTIONAL,
@@ -1532,7 +1690,10 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
                                     TransactionConcurrency concurrency =
                                         testType == TestType.PESSIMISTIC_TX ? PESSIMISTIC : OPTIMISTIC;
 
-                                    try (Transaction tx = txs.txStart(concurrency, REPEATABLE_READ)) {
+                                    TransactionIsolation isolation = testType == TestType.OPTIMISTIC_SERIALIZABLE_TX ?
+                                        SERIALIZABLE : REPEATABLE_READ;
+
+                                    try (Transaction tx = txs.txStart(concurrency, isolation)) {
                                         cache.putAll(map);
 
                                         tx.commit();
@@ -1822,6 +1983,8 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
 
                     super.sendMessage(msg.get1(), msg.get2());
                 }
+
+                blockedMsgs.clear();
             }
         }
     }
@@ -1837,6 +2000,9 @@ public class IgniteCacheClientNodeChangingTopologyTest extends GridCommonAbstrac
         OPTIMISTIC_TX,
 
         /** */
+        OPTIMISTIC_SERIALIZABLE_TX,
+
+        /** */
         PESSIMISTIC_TX,
 
         /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java
index 8500e97..7fe0138 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheCrossCacheTxFailoverTest.java
@@ -37,6 +37,7 @@ import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
@@ -58,6 +59,7 @@ import static org.apache.ignite.testframework.GridTestUtils.setMemoryMode;
 import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
 import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
 import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
 
 /**
  *
@@ -175,6 +177,13 @@ public class IgniteCacheCrossCacheTxFailoverTest extends GridCommonAbstractTest
     /**
      * @throws Exception If failed.
      */
+    public void testCrossCacheOptimisticSerializableTxFailover() throws Exception {
+        crossCacheTxFailover(PARTITIONED, true, OPTIMISTIC, SERIALIZABLE, TestMemoryMode.HEAP);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testCrossCacheOptimisticTxFailoverOffheapSwap() throws Exception {
         crossCacheTxFailover(PARTITIONED, true, OPTIMISTIC, REPEATABLE_READ, TestMemoryMode.OFFHEAP_EVICT_SWAP);
     }
@@ -424,6 +433,11 @@ public class IgniteCacheCrossCacheTxFailoverTest extends GridCommonAbstractTest
         @Override public int hashCode() {
             return (int)(key ^ (key >>> 32));
         }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(TestKey.class, this);
+        }
     }
 
     /**
@@ -446,6 +460,11 @@ public class IgniteCacheCrossCacheTxFailoverTest extends GridCommonAbstractTest
         public long value() {
             return val;
         }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(TestValue.class, this);
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java
index 8645497..8a4609b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/IgniteCacheLockFailoverSelfTest.java
@@ -21,6 +21,7 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.processors.cache.GridCacheAbstractSelfTest;
@@ -28,6 +29,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteFutureTimeoutException;
+import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
 import org.apache.ignite.testframework.GridTestUtils;
 
 /**
@@ -41,6 +43,15 @@ public class IgniteCacheLockFailoverSelfTest extends GridCacheAbstractSelfTest {
     }
 
     /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        ((TcpCommunicationSpi)cfg.getCommunicationSpi()).setSharedMemoryPort(-1);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
     @Override protected void afterTest() throws Exception {
         super.afterTest();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
index 3913957..74d2d09 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridCacheAtomicInvalidPartitionHandlingSelfTest.java
@@ -98,7 +98,11 @@ public class GridCacheAtomicInvalidPartitionHandlingSelfTest extends GridCommonA
 
         cfg.setCacheConfiguration(ccfg);
 
-        cfg.setCommunicationSpi(new DelayCommunicationSpi());
+        DelayCommunicationSpi spi = new DelayCommunicationSpi();
+
+        spi.setSharedMemoryPort(-1);
+
+        cfg.setCommunicationSpi(spi);
 
         if (testClientNode() && getTestGridName(0).equals(gridName))
             cfg.setClientMode(true);

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java
index 9546d61..02aa824 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCacheNearTxExceptionSelfTest.java
@@ -31,6 +31,7 @@ public class GridCacheNearTxExceptionSelfTest extends IgniteTxExceptionAbstractS
         return PARTITIONED;
     }
 
+    /** {@inheritDoc} */
     @Override public void testTransformBackup(){
         fail("https://issues.apache.org/jira/browse/IGNITE-1601");
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java
index 6ed25eb..20ee904 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/GridCachePartitionedTxMultiThreadedSelfTest.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.distributed.near;
 
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
 import org.apache.ignite.internal.processors.cache.IgniteTxMultiThreadedAbstractTest;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
@@ -40,11 +41,6 @@ public class GridCachePartitionedTxMultiThreadedSelfTest extends IgniteTxMultiTh
     private TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
 
     /** {@inheritDoc} */
-    @Override public void testOptimisticSerializableCommitMultithreaded() throws Exception {
-        fail("https://issues.apache.org/jira/browse/IGNITE-806");
-    }
-
-    /** {@inheritDoc} */
     @SuppressWarnings({"ConstantConditions"})
     @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
         IgniteConfiguration c = super.getConfiguration(gridName);
@@ -60,6 +56,8 @@ public class GridCachePartitionedTxMultiThreadedSelfTest extends IgniteTxMultiTh
 
         cc.setWriteSynchronizationMode(FULL_SYNC);
 
+        cc.setNearConfiguration(nearEnabled() ? new NearCacheConfiguration() : null);
+
         c.setCacheConfiguration(cc);
 
         TcpDiscoverySpi disco = new TcpDiscoverySpi();
@@ -74,6 +72,13 @@ public class GridCachePartitionedTxMultiThreadedSelfTest extends IgniteTxMultiTh
         return c;
     }
 
+    /**
+     * @return {@code True} if near cache is enabled.
+     */
+    protected boolean nearEnabled() {
+        return true;
+    }
+
     /** {@inheritDoc} */
     @Override protected int gridCount() {
         return 3;

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerUpdateAfterLoadTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerUpdateAfterLoadTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerUpdateAfterLoadTest.java
new file mode 100644
index 0000000..32e204b
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerUpdateAfterLoadTest.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.datastreamer;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+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 static org.apache.ignite.cache.CacheAtomicWriteOrderMode.CLOCK;
+import static org.apache.ignite.cache.CacheAtomicWriteOrderMode.PRIMARY;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public class DataStreamerUpdateAfterLoadTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private boolean client;
+
+    /** */
+    private static final int NODES = 4;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER);
+
+        cfg.setClientMode(client);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        startGridsMultiThreaded(NODES - 1);
+
+        client = true;
+
+        startGrid(NODES - 1);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+
+        super.afterTestsStopped();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testUpdateAfterLoad() throws Exception {
+        Ignite ignite0 = ignite(0);
+
+        for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+            int key = 0;
+
+            try (IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg)) {
+                key = testLoadAndUpdate(cache.getName(), key, false);
+
+                testLoadAndUpdate(cache.getName(), key, true);
+
+                ignite0.destroyCache(cache.getName());
+            }
+        }
+    }
+
+    /**
+     * @param cacheName Cache name.
+     * @param key Key.
+     * @param allowOverwrite Streamer flag.
+     * @return Next key.
+     * @throws Exception If failed.
+     */
+    private int testLoadAndUpdate(String cacheName, int key, boolean allowOverwrite) throws Exception {
+        for (int loadNode = 0; loadNode < NODES; loadNode++) {
+            Ignite loadIgnite = ignite(loadNode);
+
+            for (int updateNode = 0; updateNode < NODES; updateNode++) {
+                try (IgniteDataStreamer<Integer, Integer> streamer = loadIgnite.dataStreamer(cacheName)) {
+                    streamer.allowOverwrite(allowOverwrite);
+
+                    streamer.addData(key, key);
+                }
+
+                Ignite updateIgnite = ignite(updateNode);
+
+                IgniteCache<Integer, Integer> cache = updateIgnite.cache(cacheName);
+
+                if (allowOverwrite)
+                    atomicClockModeDelay(cache);
+
+                updateIgnite.cache(cacheName).put(key, key + 1);
+
+                checkValue(key, key + 1, cacheName);
+
+                key++;
+            }
+        }
+
+        return key;
+    }
+
+    /**
+     * @param key Key.
+     * @param val Value.
+     * @param cacheName Cache name.
+     */
+    private void checkValue(Integer key, Integer val, String cacheName) {
+        for (int i = 0; i < NODES; i++) {
+            IgniteCache<Integer, Integer> cache = ignite(i).cache(cacheName);
+
+            assertEquals("Unexpected value " + i, val, cache.get(key));
+        }
+    }
+
+    /**
+     * @return Cache configurations to test.
+     */
+    private List<CacheConfiguration<Integer, Integer>> cacheConfigurations() {
+        List<CacheConfiguration<Integer, Integer>> ccfgs = new ArrayList<>();
+
+        ccfgs.add(cacheConfiguration(CacheAtomicityMode.ATOMIC, PRIMARY, 1, "cache-" + ccfgs.size()));
+        ccfgs.add(cacheConfiguration(CacheAtomicityMode.ATOMIC, PRIMARY, 0, "cache-" + ccfgs.size()));
+        ccfgs.add(cacheConfiguration(CacheAtomicityMode.ATOMIC, CLOCK, 1, "cache-" + ccfgs.size()));
+        ccfgs.add(cacheConfiguration(CacheAtomicityMode.TRANSACTIONAL, null, 1, "cache-" + ccfgs.size()));
+        ccfgs.add(cacheConfiguration(CacheAtomicityMode.TRANSACTIONAL, null, 0, "cache-" + ccfgs.size()));
+
+        return ccfgs;
+    }
+
+    /**
+     * @param atomicityMode Cache atomicity mode.
+     * @param writeOrderMode Cache write order mode.
+     * @param backups Number of backups.
+     * @param name Cache name.
+     * @return Cache configuration.
+     */
+    private CacheConfiguration<Integer, Integer> cacheConfiguration(CacheAtomicityMode atomicityMode,
+        CacheAtomicWriteOrderMode writeOrderMode,
+        int backups,
+        String name) {
+        CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>();
+
+        ccfg.setName(name);
+        ccfg.setAtomicityMode(atomicityMode);
+        ccfg.setBackups(backups);
+        ccfg.setAtomicWriteOrderMode(writeOrderMode);
+        ccfg.setWriteSynchronizationMode(FULL_SYNC);
+
+        return ccfg;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java b/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java
index cf2ff41..a6dfc9c 100644
--- a/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/loadtests/hashmap/GridHashMapLoadTest.java
@@ -26,6 +26,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.testframework.junits.GridTestKernalContext;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.testframework.junits.logger.GridTestLog4jLogger;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Tests hashmap load.
@@ -81,7 +82,10 @@ public class GridHashMapLoadTest extends GridCommonAbstractTest {
 
             map.put(key, new GridCacheMapEntry(ctx, ctx.toCacheKeyObject(key),
                 key.hashCode(), ctx.toCacheObject(val), null, 1) {
-                @Override public boolean tmLock(IgniteInternalTx tx, long timeout) {
+                @Override public boolean tmLock(IgniteInternalTx tx,
+                    long timeout,
+                    @Nullable GridCacheVersion serOrder,
+                    GridCacheVersion serReadVer) {
                     return false;
                 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java b/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java
index cc5226f..f50a732 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/swapspace/inmemory/GridTestSwapSpaceSpi.java
@@ -180,6 +180,14 @@ public class GridTestSwapSpaceSpi extends IgniteSpiAdapter implements SwapSpaceS
     }
 
     /**
+     *
+     */
+    public void clearAll() {
+        for (Space space : spaces.values())
+            space.clear();
+    }
+
+    /**
      * Gets space, creates if does not exist.
      *
      * @param spaceName Space name.

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
index e4c2129..28d5c73 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
@@ -77,6 +77,8 @@ import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.testframework.junits.GridAbstractTest;
 import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
 import org.apache.ignite.transactions.TransactionRollbackException;
 import org.jetbrains.annotations.Nullable;
 
@@ -1026,8 +1028,23 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest {
      * @throws Exception If failed.
      */
     protected <T> T doInTransaction(Ignite ignite, Callable<T> clo) throws Exception {
+        return doInTransaction(ignite, PESSIMISTIC, REPEATABLE_READ, clo);
+    }
+
+    /**
+     * @param ignite Ignite instance.
+     * @param concurrency Transaction concurrency.
+     * @param isolation Transaction isolation.
+     * @param clo Closure.
+     * @return Result of closure execution.
+     * @throws Exception If failed.
+     */
+    protected <T> T doInTransaction(Ignite ignite,
+        TransactionConcurrency concurrency,
+        TransactionIsolation isolation,
+        Callable<T> clo) throws Exception {
         while (true) {
-            try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
+            try (Transaction tx = ignite.transactions().txStart(concurrency, isolation)) {
                 T res = clo.call();
 
                 tx.commit();

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
index d2904e87..c62a131 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
@@ -122,6 +122,7 @@ import org.apache.ignite.internal.processors.datastreamer.DataStreamProcessorSel
 import org.apache.ignite.internal.processors.datastreamer.DataStreamerImplSelfTest;
 import org.apache.ignite.internal.processors.datastreamer.DataStreamerMultiThreadedSelfTest;
 import org.apache.ignite.internal.processors.datastreamer.DataStreamerMultinodeCreateCacheTest;
+import org.apache.ignite.internal.processors.datastreamer.DataStreamerUpdateAfterLoadTest;
 import org.apache.ignite.testframework.GridTestUtils;
 
 /**
@@ -213,7 +214,8 @@ public class IgniteCacheTestSuite extends TestSuite {
         suite.addTestSuite(GridCacheAffinityApiSelfTest.class);
         suite.addTestSuite(GridCacheStoreValueBytesSelfTest.class);
         GridTestUtils.addTestIfNeeded(suite, DataStreamProcessorSelfTest.class, ignoredTests);
-        suite.addTestSuite(DataStreamerMultiThreadedSelfTest.class);
+        GridTestUtils.addTestIfNeeded(suite, DataStreamerUpdateAfterLoadTest.class, ignoredTests);
+            suite.addTestSuite(DataStreamerMultiThreadedSelfTest.class);
         suite.addTestSuite(DataStreamerMultinodeCreateCacheTest.class);
         suite.addTestSuite(DataStreamerImplSelfTest.class);
         GridTestUtils.addTestIfNeeded(suite, GridCacheEntryMemorySizeSelfTest.class, ignoredTests);

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
index 93bd26c..5138dac 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite2.java
@@ -36,6 +36,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCachePartitionMapUpdate
 import org.apache.ignite.internal.processors.cache.IgniteDynamicCacheAndNodeStop;
 import org.apache.ignite.internal.processors.cache.distributed.CacheLoadingConcurrentGridStartSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.GridCachePartitionNotLoadedEventSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.GridCachePartitionedNearDisabledTxMultiThreadedSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.GridCacheTransformEventSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheClientNodeChangingTopologyTest;
 import org.apache.ignite.internal.processors.cache.distributed.IgniteCacheClientNodePartitionsExchangeTest;
@@ -190,6 +191,7 @@ public class IgniteCacheTestSuite2 extends TestSuite {
         suite.addTest(new TestSuite(GridCacheDhtInternalEntrySelfTest.class));
         suite.addTest(new TestSuite(GridCacheDhtMappingSelfTest.class));
         suite.addTest(new TestSuite(GridCachePartitionedTxMultiThreadedSelfTest.class));
+        suite.addTest(new TestSuite(GridCachePartitionedNearDisabledTxMultiThreadedSelfTest.class));
         suite.addTest(new TestSuite(GridCacheDhtPreloadSelfTest.class));
         suite.addTest(new TestSuite(GridCacheDhtPreloadOffHeapSelfTest.class));
         suite.addTest(new TestSuite(GridCacheDhtPreloadBigDataSelfTest.class));

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
new file mode 100644
index 0000000..0f86c4c
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite5.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.testsuites;
+
+import junit.framework.TestSuite;
+import org.apache.ignite.internal.processors.cache.CacheNearReaderUpdateTest;
+import org.apache.ignite.internal.processors.cache.CacheSerializableTransactionsTest;
+
+/**
+ * Test suite.
+ */
+public class IgniteCacheTestSuite5 extends TestSuite {
+    /**
+     * @return IgniteCache test suite.
+     * @throws Exception Thrown in case of the failure.
+     */
+    public static TestSuite suite() throws Exception {
+        TestSuite suite = new TestSuite("IgniteCache Test Suite part 5");
+
+        suite.addTestSuite(CacheSerializableTransactionsTest.class);
+        suite.addTestSuite(CacheNearReaderUpdateTest.class);
+
+        return suite;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/config/benchmark-multicast.properties
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/benchmark-multicast.properties b/modules/yardstick/config/benchmark-multicast.properties
index 82bf766..82fc3f8 100644
--- a/modules/yardstick/config/benchmark-multicast.properties
+++ b/modules/yardstick/config/benchmark-multicast.properties
@@ -86,5 +86,8 @@ CONFIGS="\
 -cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgnitePutTxOffHeapValuesBenchmark -sn IgniteNode -ds ${ver}tx-put-offheap-val-1-backup,\
 -cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-offheap-1-backup,\
 -cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryJoinOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-join-offheap-1-backup,\
--cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryPutOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-put-offheap-1-backup\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryPutOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-put-offheap-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -bs 100 -dn IgnitePutAllBenchmark -sn IgniteNode -ds ${ver}atomic-putAll-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -bs 100 -dn IgnitePutAllTxBenchmark -sn IgniteNode -ds ${ver}tx-putAll-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-multicast-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -bs 100 -dn IgnitePutAllSerializableTxBenchmark -sn IgniteNode -ds ${ver}tx-putAllSerializable-1-backup\
 "

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountSerializableTxBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountSerializableTxBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountSerializableTxBenchmark.java
new file mode 100644
index 0000000..32e7653
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountSerializableTxBenchmark.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionOptimisticException;
+import org.apache.ignite.yardstick.cache.model.Account;
+
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ *
+ */
+public class IgniteAccountSerializableTxBenchmark extends IgniteAccountTxAbstractBenchmark {
+    /** */
+    private static final int ACCOUNT_NUMBER = 3;
+
+    /** {@inheritDoc} */
+    @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+        Set<Integer> accountIds = new HashSet<>();
+
+        while (accountIds.size() < ACCOUNT_NUMBER)
+            accountIds.add(nextRandom(args.range()));
+
+        while (true) {
+            try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                Map<Integer, Account> accounts = (Map)cache.getAll(accountIds);
+
+                if (accounts.size() != ACCOUNT_NUMBER)
+                    throw new Exception("Failed to find accounts: " + accountIds);
+
+                Integer fromId = accountIds.iterator().next();
+
+                int fromBalance = accounts.get(fromId).balance();
+
+                for (Integer id : accountIds) {
+                    if (id.equals(fromId))
+                        continue;
+
+                    Account account = accounts.get(id);
+
+                    if (fromBalance > 0) {
+                        fromBalance--;
+
+                        cache.put(id, new Account(account.balance() + 1));
+                    }
+                }
+
+                cache.put(fromId, new Account(fromBalance));
+
+                tx.commit();
+            }
+            catch (TransactionOptimisticException e) {
+                continue;
+            }
+
+            break;
+        }
+
+        return true;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxAbstractBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxAbstractBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxAbstractBenchmark.java
new file mode 100644
index 0000000..0266a3c
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxAbstractBenchmark.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.yardstick.cache.model.Account;
+import org.yardstickframework.BenchmarkConfiguration;
+
+import static org.yardstickframework.BenchmarkUtils.println;
+
+/**
+ *
+ */
+public abstract class IgniteAccountTxAbstractBenchmark extends IgniteCacheAbstractBenchmark {
+    /** */
+    protected IgniteTransactions txs;
+
+    /** {@inheritDoc} */
+    @Override public void setUp(BenchmarkConfiguration cfg) throws Exception {
+        super.setUp(cfg);
+
+        txs = ignite().transactions();
+
+        println(cfg, "Populating data...");
+
+        long start = System.nanoTime();
+
+        try (IgniteDataStreamer<Integer, Account> dataLdr = ignite().dataStreamer(cache.getName())) {
+            for (int i = 0; i < args.range() && !Thread.currentThread().isInterrupted(); i++) {
+                dataLdr.addData(i, new Account(100_000));
+
+                if (i % 100000 == 0)
+                    println(cfg, "Populated accounts: " + i);
+            }
+        }
+
+        println(cfg, "Finished populating data in " + ((System.nanoTime() - start) / 1_000_000) + " ms.");
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Integer, Object> cache() {
+        return ignite().cache("tx");
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxBenchmark.java
new file mode 100644
index 0000000..78e675e
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteAccountTxBenchmark.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.yardstick.cache.model.Account;
+
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+
+/**
+ *
+ */
+public class IgniteAccountTxBenchmark extends IgniteAccountTxAbstractBenchmark {
+    /** */
+    private static final int ACCOUNT_NUMBER = 3;
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+        Set<Integer> accountIds = new TreeSet<>();
+
+        while (accountIds.size() < ACCOUNT_NUMBER)
+            accountIds.add(nextRandom(args.range()));
+
+        try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) {
+            Map<Integer, Account> accounts = (Map)cache.getAll(accountIds);
+
+            if (accounts.size() != ACCOUNT_NUMBER)
+                throw new Exception("Failed to find accounts: " + accountIds);
+
+            Integer fromId = accountIds.iterator().next();
+
+            int fromBalance = accounts.get(fromId).balance();
+
+            for (Integer id : accountIds) {
+                if (id.equals(fromId))
+                    continue;
+
+                Account account = accounts.get(id);
+
+                if (fromBalance > 0) {
+                    fromBalance--;
+
+                    cache.put(id, new Account(account.balance() + 1));
+                }
+            }
+
+            cache.put(fromId, new Account(fromBalance));
+
+            tx.commit();
+        }
+
+        return true;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java
index 1260f9c..22a9eac 100644
--- a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgniteCacheAbstractBenchmark.java
@@ -88,6 +88,9 @@ public abstract class IgniteCacheAbstractBenchmark extends IgniteAbstractBenchma
         /** */
         final int max;
 
+        /** */
+        final ThreadLocalRandom rnd;
+
         /**
          * @param min Min.
          * @param max Max.
@@ -95,13 +98,15 @@ public abstract class IgniteCacheAbstractBenchmark extends IgniteAbstractBenchma
         private ThreadRange(int min, int max) {
             this.min = min;
             this.max = max;
+
+            rnd = ThreadLocalRandom.current();
         }
 
         /**
          * @return Next random key.
          */
         int nextRandom() {
-            return ThreadLocalRandom.current().nextInt(min, max);
+            return rnd.nextInt(min, max);
         }
     }
 }
\ No newline at end of file


[18/31] ignite git commit: Muted test

Posted by ra...@apache.org.
Muted test


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

Branch: refs/heads/ignite-1790
Commit: e12e184ea609c3015bc9ffcb737629f0baf74734
Parents: a4d625d
Author: ashutak <as...@gridgain.com>
Authored: Tue Oct 27 16:38:56 2015 +0300
Committer: ashutak <as...@gridgain.com>
Committed: Tue Oct 27 16:38:56 2015 +0300

----------------------------------------------------------------------
 .../processors/cache/IgniteCacheCreateRestartSelfTest.java         | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e12e184e/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheCreateRestartSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheCreateRestartSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheCreateRestartSelfTest.java
index 6f32d36..e8babf7 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheCreateRestartSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheCreateRestartSelfTest.java
@@ -71,6 +71,8 @@ public class IgniteCacheCreateRestartSelfTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     public void testStopOriginatingNode() throws Exception {
+        fail("https://issues.apache.org/jira/browse/IGNITE-1797");
+        
         startGrids(NODES);
 
         ThreadLocalRandom rnd = ThreadLocalRandom.current();


[07/31] ignite git commit: IGNITE-1701. Bump Spark dependenency to 1.5.1 (the latest stable)

Posted by ra...@apache.org.
IGNITE-1701. Bump Spark dependenency to 1.5.1 (the latest stable)


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

Branch: refs/heads/ignite-1790
Commit: 1334e77a7eb23d575de9097f519a64b4678e9dff
Parents: ef785cb
Author: Konstantin Boudnik <co...@wandisco.com>
Authored: Thu Oct 15 14:26:47 2015 -0700
Committer: Konstantin Boudnik <co...@wandisco.com>
Committed: Mon Oct 26 13:13:56 2015 -0700

----------------------------------------------------------------------
 DEVNOTES.txt               | 3 ++-
 modules/spark-2.10/pom.xml | 4 ++--
 modules/spark/pom.xml      | 4 ++--
 parent/pom.xml             | 1 +
 4 files changed, 7 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1334e77a/DEVNOTES.txt
----------------------------------------------------------------------
diff --git a/DEVNOTES.txt b/DEVNOTES.txt
index e8e3741..ea9cf17 100644
--- a/DEVNOTES.txt
+++ b/DEVNOTES.txt
@@ -19,9 +19,10 @@ NOTE: JDK version should be 1.7.0-* or >= 1.8.0-u40.
 
 Ignite Hadoop Accelerator Maven Build Instructions
 ============================================
-mvn clean package -DskipTests -Dignite.edition=hadoop [-Dhadoop.version=X.X.X]
+mvn clean package -DskipTests -Dignite.edition=hadoop [-Dhadoop.version=X.X.X] [-Dspark.version=x.y.z]
 
 Use 'hadoop.version' parameter to build Ignite against a specific Hadoop version.
+Use 'spark.version' parameter to build ignite-spark module for a specific Spark version.
 
 Look for apache-ignite-hadoop-<version>-bin.zip in ./target/bin directory. Resulting binary
 assembly will also include integration module for Apache Spark.

http://git-wip-us.apache.org/repos/asf/ignite/blob/1334e77a/modules/spark-2.10/pom.xml
----------------------------------------------------------------------
diff --git a/modules/spark-2.10/pom.xml b/modules/spark-2.10/pom.xml
index 316b13b..4697693 100644
--- a/modules/spark-2.10/pom.xml
+++ b/modules/spark-2.10/pom.xml
@@ -58,13 +58,13 @@
         <dependency>
             <groupId>org.apache.spark</groupId>
             <artifactId>spark-core_2.10</artifactId>
-            <version>1.3.1</version>
+            <version>${spark.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.apache.spark</groupId>
             <artifactId>spark-sql_2.10</artifactId>
-            <version>1.3.1</version>
+            <version>${spark.version}</version>
         </dependency>
 
         <!-- Test dependencies -->

http://git-wip-us.apache.org/repos/asf/ignite/blob/1334e77a/modules/spark/pom.xml
----------------------------------------------------------------------
diff --git a/modules/spark/pom.xml b/modules/spark/pom.xml
index 95e05d8..942652c 100644
--- a/modules/spark/pom.xml
+++ b/modules/spark/pom.xml
@@ -58,13 +58,13 @@
         <dependency>
             <groupId>org.apache.spark</groupId>
             <artifactId>spark-core_2.11</artifactId>
-            <version>1.3.1</version>
+            <version>${spark.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.apache.spark</groupId>
             <artifactId>spark-sql_2.11</artifactId>
-            <version>1.3.1</version>
+            <version>${spark.version}</version>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/ignite/blob/1334e77a/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index ba44c85..765ecf1 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -36,6 +36,7 @@
     <properties>
         <ignite.edition>fabric</ignite.edition>
         <hadoop.version>2.4.1</hadoop.version>
+        <spark.version>1.5.1</spark.version>
         <spring.version>4.1.0.RELEASE</spring.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <maven.build.timestamp.format>MMMM d yyyy</maven.build.timestamp.format>


[04/31] ignite git commit: Merge branch 'master' into ignite-1747

Posted by ra...@apache.org.
Merge branch 'master' into ignite-1747


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

Branch: refs/heads/ignite-1790
Commit: b12663fc44b2a0b8d0d867aa2c762e62b0c71250
Parents: 0e48722 15cc1bd
Author: Raul Kripalani <ra...@apache.org>
Authored: Mon Oct 26 13:05:46 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Mon Oct 26 13:05:46 2015 +0000

----------------------------------------------------------------------
 .../internal/portable/PortableContext.java      |  12 +--
 .../ignite/internal/util/nio/GridNioServer.java |   2 +-
 ...ledFairAffinityMultiNodeFullApiSelfTest.java |   8 +-
 ...icOffHeapTieredMultiNodeFullApiSelfTest.java |   7 +-
 .../replicated/GridReplicatedTxPreloadTest.java |   7 +-
 .../nio/IgniteExceptionInNioWorkerSelfTest.java | 105 +++++++++++++++++++
 .../tcp/TcpClientDiscoverySpiSelfTest.java      |   4 +-
 .../ignite/testsuites/IgniteBasicTestSuite.java |   3 +
 .../CacheHibernateBlobStoreSelfTest.java        |   6 +-
 .../yardstick/IgniteBenchmarkArguments.java     |  11 ++
 .../cache/IgniteCacheAbstractBenchmark.java     |  63 +++++++++++
 .../cache/IgnitePutAllTxBenchmark.java          |   6 +-
 12 files changed, 220 insertions(+), 14 deletions(-)
----------------------------------------------------------------------



[27/31] ignite git commit: ignite-1607 Implemented deadlock-free optimistic serializable tx mode

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java
index fe519a7..3c3527a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearCacheAdapter.java
@@ -221,34 +221,9 @@ public abstract class GridNearCacheAdapter<K, V> extends GridDistributedCacheAda
         return true;
     }
 
-    /** {@inheritDoc} */
-    @SuppressWarnings({"unchecked", "RedundantCast"})
-    @Override public IgniteInternalFuture<Object> readThroughAllAsync(
-        Collection<KeyCacheObject> keys,
-        boolean reload,
-        boolean skipVals,
-        IgniteInternalTx tx,
-        @Nullable UUID subjId,
-        String taskName,
-        IgniteBiInClosure<KeyCacheObject, Object> vis
-    ) {
-        return (IgniteInternalFuture)loadAsync(tx,
-            keys,
-            reload,
-            /*force primary*/false,
-            subjId,
-            taskName,
-            /*deserialize portable*/true,
-            /*expiry policy*/null,
-            skipVals,
-            /*skip store*/false,
-            /*can remap*/true);
-    }
-
     /**
      * @param tx Transaction.
      * @param keys Keys to load.
-     * @param reload Reload flag.
      * @param forcePrimary Force primary flag.
      * @param subjId Subject ID.
      * @param taskName Task name.
@@ -256,11 +231,11 @@ public abstract class GridNearCacheAdapter<K, V> extends GridDistributedCacheAda
      * @param expiryPlc Expiry policy.
      * @param skipVal Skip value flag.
      * @param skipStore Skip store flag.
+     * @param canRemap Can remap flag.
      * @return Loaded values.
      */
     public IgniteInternalFuture<Map<K, V>> loadAsync(@Nullable IgniteInternalTx tx,
         @Nullable Collection<KeyCacheObject> keys,
-        boolean reload,
         boolean forcePrimary,
         @Nullable UUID subjId,
         String taskName,
@@ -280,7 +255,6 @@ public abstract class GridNearCacheAdapter<K, V> extends GridDistributedCacheAda
         GridNearGetFuture<K, V> fut = new GridNearGetFuture<>(ctx,
             keys,
             !skipStore,
-            reload,
             forcePrimary,
             txx,
             subjId,
@@ -288,7 +262,9 @@ public abstract class GridNearCacheAdapter<K, V> extends GridDistributedCacheAda
             deserializePortable,
             expiry,
             skipVal,
-            canRemap);
+            canRemap,
+            false,
+            false);
 
         // init() will register future for responses if future has remote mappings.
         fut.init();

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 2ae03d3..d558cc5 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
@@ -46,7 +46,7 @@ import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ;
 @SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext", "TooBroadScope"})
 public class GridNearCacheEntry extends GridDistributedCacheEntry {
     /** */
-    private static final int NEAR_SIZE_OVERHEAD = 36;
+    private static final int NEAR_SIZE_OVERHEAD = 36 + 16;
 
     /** Topology version at the moment when value was initialized from primary node. */
     private volatile long topVer = -1L;
@@ -58,6 +58,9 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
     /** Partition. */
     private int part;
 
+    /** */
+    private short evictReservations;
+
     /**
      * @param ctx Cache context.
      * @param key Cache key.
@@ -316,15 +319,21 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
         primaryNode(primaryNodeId, topVer);
     }
 
-    /**
-     * This method should be called only when committing optimistic transactions.
-     *
+    /*
      * @param dhtVer DHT version to record.
+     * @return {@code False} if given version is lower then existing version.
      */
-    public synchronized void recordDhtVersion(GridCacheVersion dhtVer) {
-        // Version manager must be updated separately, when adding DHT version
-        // to transaction entries.
-        this.dhtVer = dhtVer;
+    public final boolean recordDhtVersion(GridCacheVersion dhtVer) {
+        assert dhtVer != null;
+        assert Thread.holdsLock(this);
+
+        if (this.dhtVer == null || this.dhtVer.compareTo(dhtVer) <= 0) {
+            this.dhtVer = dhtVer;
+
+            return true;
+        }
+
+        return false;
     }
 
     /** {@inheritDoc} */
@@ -332,7 +341,6 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
         UUID subjId, String taskName) throws IgniteCheckedException {
         return cctx.near().loadAsync(tx,
             F.asList(key),
-            reload,
             /*force primary*/false,
             subjId,
             taskName,
@@ -350,7 +358,6 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
      * @param val New value.
      * @param ver Version to use.
      * @param dhtVer DHT version received from remote node.
-     * @param expVer Optional version to match.
      * @param ttl Time to live.
      * @param expireTime Expiration time.
      * @param evt Event flag.
@@ -366,14 +373,13 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
         CacheObject val,
         GridCacheVersion ver,
         GridCacheVersion dhtVer,
-        @Nullable GridCacheVersion expVer,
         long ttl,
         long expireTime,
         boolean evt,
         AffinityTopologyVersion topVer,
         UUID subjId)
         throws IgniteCheckedException, GridCacheEntryRemovedException {
-        boolean valid = valid(tx != null ? tx.topologyVersion() : cctx.affinity().affinityTopologyVersion());
+        assert dhtVer != null;
 
         GridCacheVersion enqueueVer = null;
 
@@ -389,28 +395,25 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
                 CacheObject old = this.val;
                 boolean hasVal = hasValueUnlocked();
 
-                if (isNew() || !valid || expVer == null || expVer.equals(this.dhtVer)) {
+                if (this.dhtVer == null || this.dhtVer.compareTo(dhtVer) < 0) {
                     primaryNode(primaryNodeId, topVer);
 
-                    // Change entry only if dht version has changed.
-                    if (!dhtVer.equals(dhtVersion())) {
-                        update(val, expireTime, ttl, ver);
+                    update(val, expireTime, ttl, ver);
 
-                        if (cctx.deferredDelete() && !isInternal()) {
-                            boolean deleted = val == null;
+                    if (cctx.deferredDelete() && !isInternal()) {
+                        boolean deleted = val == null;
 
-                            if (deleted != deletedUnlocked()) {
-                                deletedUnlocked(deleted);
+                        if (deleted != deletedUnlocked()) {
+                            deletedUnlocked(deleted);
 
-                                if (deleted)
-                                    enqueueVer = ver;
-                            }
+                            if (deleted)
+                                enqueueVer = ver;
                         }
+                    }
 
-                        recordDhtVersion(dhtVer);
+                    this.dhtVer = dhtVer;
 
-                        ret = true;
-                    }
+                    ret = true;
                 }
 
                 if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ))
@@ -647,6 +650,32 @@ public class GridNearCacheEntry extends GridDistributedCacheEntry {
     }
 
     /**
+     * @throws GridCacheEntryRemovedException If entry was removed.
+     */
+    public synchronized void reserveEviction() throws GridCacheEntryRemovedException {
+        checkObsolete();
+
+        evictReservations++;
+    }
+
+    /**
+     *
+     */
+    public synchronized void releaseEviction() {
+        assert evictReservations > 0 : this;
+        assert !obsolete() : this;
+
+        evictReservations--;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean evictionDisabled() {
+        assert Thread.holdsLock(this);
+
+        return evictReservations > 0;
+    }
+
+    /**
      * @param nodeId Primary node ID.
      * @param topVer Topology version.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
index eca2f71..ae1d43c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetFuture.java
@@ -24,7 +24,6 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
@@ -38,19 +37,17 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFuture;
 import org.apache.ignite.internal.processors.cache.GridCacheMessage;
 import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
 import org.apache.ignite.internal.processors.cache.KeyCacheObject;
 import org.apache.ignite.internal.processors.cache.distributed.GridFutureRemapTimeoutObject;
+import org.apache.ignite.internal.processors.cache.distributed.dht.CacheDistributedGetFutureAdapter;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtFuture;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalEx;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.util.GridLeanMap;
-import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -59,6 +56,7 @@ import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.CIX1;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.P1;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -66,83 +64,31 @@ import org.apache.ignite.lang.IgniteClosure;
 import org.apache.ignite.lang.IgniteUuid;
 import org.jetbrains.annotations.Nullable;
 
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_NEAR_GET_MAX_REMAPS;
-import static org.apache.ignite.IgniteSystemProperties.getInteger;
 import static org.apache.ignite.transactions.TransactionIsolation.READ_COMMITTED;
 
 /**
  *
  */
-public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Map<K, V>>
-    implements GridCacheFuture<Map<K, V>> {
+public final class GridNearGetFuture<K, V> extends CacheDistributedGetFutureAdapter<K, V> {
     /** */
     private static final long serialVersionUID = 0L;
 
-    /** Default max remap count value. */
-    public static final int DFLT_MAX_REMAP_CNT = 3;
-
     /** Logger reference. */
     private static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
 
     /** Logger. */
     private static IgniteLogger log;
 
-    /** Maximum number of attempts to remap key to the same primary node. */
-    private static final int MAX_REMAP_CNT = getInteger(IGNITE_NEAR_GET_MAX_REMAPS, DFLT_MAX_REMAP_CNT);
-
-    /** Context. */
-    private final GridCacheContext<K, V> cctx;
-
-    /** Keys. */
-    private Collection<KeyCacheObject> keys;
-
-    /** Reload flag. */
-    private boolean reload;
-
-    /** Read through flag. */
-    private boolean readThrough;
-
-    /** Force primary flag. */
-    private boolean forcePrimary;
-
-    /** Future ID. */
-    private IgniteUuid futId;
-
-    /** Version. */
-    private GridCacheVersion ver;
-
     /** Transaction. */
     private IgniteTxLocalEx tx;
 
-    /** Trackable flag. */
-    private boolean trackable;
-
-    /** Remap count. */
-    private AtomicInteger remapCnt = new AtomicInteger();
-
-    /** Subject ID. */
-    private UUID subjId;
-
-    /** Task name. */
-    private String taskName;
-
-    /** Whether to deserialize portable objects. */
-    private boolean deserializePortable;
-
-    /** Skip values flag. */
-    private boolean skipVals;
-
-    /** Expiry policy. */
-    private IgniteCacheExpiryPolicy expiryPlc;
-
-    /** Flag indicating that get should be done on a locked topology version. */
-    private final boolean canRemap;
+    /** */
+    private GridCacheVersion ver;
 
     /**
      * @param cctx Context.
      * @param keys Keys.
      * @param readThrough Read through flag.
-     * @param reload Reload flag.
      * @param forcePrimary If {@code true} get will be performed on primary node even if
      *      called on backup node.
      * @param tx Transaction.
@@ -151,12 +97,14 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
      * @param deserializePortable Deserialize portable flag.
      * @param expiryPlc Expiry policy.
      * @param skipVals Skip values flag.
+     * @param canRemap Flag indicating whether future can be remapped on a newer topology version.
+     * @param needVer If {@code true} returns values as tuples containing value and version.
+     * @param keepCacheObjects Keep cache objects flag.
      */
     public GridNearGetFuture(
         GridCacheContext<K, V> cctx,
         Collection<KeyCacheObject> keys,
         boolean readThrough,
-        boolean reload,
         boolean forcePrimary,
         @Nullable IgniteTxLocalEx tx,
         @Nullable UUID subjId,
@@ -164,24 +112,26 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
         boolean deserializePortable,
         @Nullable IgniteCacheExpiryPolicy expiryPlc,
         boolean skipVals,
-        boolean canRemap
+        boolean canRemap,
+        boolean needVer,
+        boolean keepCacheObjects
     ) {
-        super(cctx.kernalContext(), CU.<K, V>mapsReducer(keys.size()));
+        super(cctx,
+            keys,
+            readThrough,
+            forcePrimary,
+            subjId,
+            taskName,
+            deserializePortable,
+            expiryPlc,
+            skipVals,
+            canRemap,
+            needVer,
+            keepCacheObjects);
 
         assert !F.isEmpty(keys);
 
-        this.cctx = cctx;
-        this.keys = keys;
-        this.readThrough = readThrough;
-        this.reload = reload;
-        this.forcePrimary = forcePrimary;
         this.tx = tx;
-        this.subjId = subjId;
-        this.taskName = taskName;
-        this.deserializePortable = deserializePortable;
-        this.expiryPlc = expiryPlc;
-        this.skipVals = skipVals;
-        this.canRemap = canRemap;
 
         futId = IgniteUuid.randomUuid();
 
@@ -318,16 +268,17 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
 
         Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings = U.newHashMap(affNodes.size());
 
-        Map<KeyCacheObject, GridCacheVersion> savedVers = null;
+        Map<KeyCacheObject, GridNearCacheEntry> savedEntries = null;
 
         // Assign keys to primary nodes.
         for (KeyCacheObject key : keys)
-            savedVers = map(key, mappings, topVer, mapped, savedVers);
+            savedEntries = map(key, mappings, topVer, mapped, savedEntries);
 
         if (isDone())
             return;
 
-        final Map<KeyCacheObject, GridCacheVersion> saved = savedVers;
+        final Map<KeyCacheObject, GridNearCacheEntry> saved = savedEntries != null ? savedEntries :
+            Collections.<KeyCacheObject, GridNearCacheEntry>emptyMap();
 
         final int keysSize = keys.size();
 
@@ -346,7 +297,6 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                         -1,
                         mappedKeys,
                         readThrough,
-                        reload,
                         topVer,
                         subjId,
                         taskName == null ? 0 : taskName.hashCode(),
@@ -405,7 +355,6 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                     ver,
                     mappedKeys,
                     readThrough,
-                    reload,
                     topVer,
                     subjId,
                     taskName == null ? 0 : taskName.hashCode(),
@@ -434,43 +383,64 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
      * @param key Key to map.
      * @param topVer Topology version
      * @param mapped Previously mapped.
-     * @param savedVers Saved versions.
+     * @param saved Reserved near cache entries.
      * @return Map.
      */
-    private Map<KeyCacheObject, GridCacheVersion> map(
+    private Map<KeyCacheObject, GridNearCacheEntry> map(
         KeyCacheObject key,
         Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mappings,
         AffinityTopologyVersion topVer,
         Map<ClusterNode, LinkedHashMap<KeyCacheObject, Boolean>> mapped,
-        Map<KeyCacheObject, GridCacheVersion> savedVers
+        Map<KeyCacheObject, GridNearCacheEntry> saved
     ) {
         final GridNearCacheAdapter near = cache();
 
         // Allow to get cached value from the local node.
         boolean allowLocRead = !forcePrimary || cctx.affinity().primary(cctx.localNode(), key, topVer);
 
-        GridCacheEntryEx entry = allowLocRead ? near.peekEx(key) : null;
-
         while (true) {
+            GridNearCacheEntry entry = allowLocRead ? (GridNearCacheEntry)near.peekEx(key) : null;
+
             try {
                 CacheObject v = null;
+                GridCacheVersion ver = null;
 
                 boolean isNear = entry != null;
 
                 // First we peek into near cache.
-                if (isNear)
-                    v = entry.innerGet(tx,
-                        /*swap*/false,
-                        /*read-through*/false,
-                        /*fail-fast*/true,
-                        /*unmarshal*/true,
-                        /*metrics*/true,
-                        /*events*/!skipVals,
-                        /*temporary*/false,
-                        subjId,
-                        null,
-                        taskName,
-                        expiryPlc);
+                if (isNear) {
+                    if (needVer) {
+                        T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                            null,
+                            /*swap*/true,
+                            /*unmarshal*/true,
+                            /**update-metrics*/true,
+                            /*event*/!skipVals,
+                            subjId,
+                            null,
+                            taskName,
+                            expiryPlc);
+
+                        if (res != null) {
+                            v = res.get1();
+                            ver = res.get2();
+                        }
+                    }
+                    else {
+                        v = entry.innerGet(tx,
+                            /*swap*/false,
+                            /*read-through*/false,
+                            /*fail-fast*/true,
+                            /*unmarshal*/true,
+                            /*metrics*/true,
+                            /*events*/!skipVals,
+                            /*temporary*/false,
+                            subjId,
+                            null,
+                            taskName,
+                            expiryPlc);
+                    }
+                }
 
                 ClusterNode affNode = null;
 
@@ -486,18 +456,37 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                         if (dhtEntry != null) {
                             boolean isNew = dhtEntry.isNewLocked() || !dhtEntry.valid(topVer);
 
-                            v = dhtEntry.innerGet(tx,
-                                /*swap*/true,
-                                /*read-through*/false,
-                                /*fail-fast*/true,
-                                /*unmarshal*/true,
-                                /*update-metrics*/false,
-                                /*events*/!isNear && !skipVals,
-                                /*temporary*/false,
-                                subjId,
-                                null,
-                                taskName,
-                                expiryPlc);
+                            if (needVer) {
+                                T2<CacheObject, GridCacheVersion> res = dhtEntry.innerGetVersioned(
+                                    null,
+                                    /*swap*/true,
+                                    /*unmarshal*/true,
+                                    /**update-metrics*/false,
+                                    /*event*/!isNear && !skipVals,
+                                    subjId,
+                                    null,
+                                    taskName,
+                                    expiryPlc);
+
+                                if (res != null) {
+                                    v = res.get1();
+                                    ver = res.get2();
+                                }
+                            }
+                            else {
+                                v = dhtEntry.innerGet(tx,
+                                    /*swap*/true,
+                                    /*read-through*/false,
+                                    /*fail-fast*/true,
+                                    /*unmarshal*/true,
+                                    /*update-metrics*/false,
+                                    /*events*/!isNear && !skipVals,
+                                    /*temporary*/false,
+                                    subjId,
+                                    null,
+                                    taskName,
+                                    expiryPlc);
+                            }
 
                             // Entry was not in memory or in swap, so we remove it from cache.
                             if (v == null && isNew && dhtEntry.markObsoleteIfEmpty(ver))
@@ -515,7 +504,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                                 onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache " +
                                     "(all partition nodes left the grid)."));
 
-                                return savedVers;
+                                return saved;
                             }
 
                             if (!affNode.isLocal() && cctx.cache().configuration().isStatisticsEnabled() && !skipVals)
@@ -534,14 +523,29 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                     }
                 }
 
-                if (v != null && !reload) {
-                    K key0 = key.value(cctx.cacheObjectContext(), true);
-                    V val0 = v.value(cctx.cacheObjectContext(), true);
+                if (v != null) {
+                    if (needVer) {
+                        V val0 = (V)new T2<>(skipVals ? true : v, ver);
+
+                        add(new GridFinishedFuture<>(Collections.singletonMap((K)key, val0)));
+                    }
+                    else {
+                        if (keepCacheObjects) {
+                            K key0 = (K)key;
+                            V val0 = (V)(skipVals ? true : v);
+
+                            add(new GridFinishedFuture<>(Collections.singletonMap(key0, val0)));
+                        }
+                        else {
+                            K key0 = key.value(cctx.cacheObjectContext(), true);
+                            V val0 = v.value(cctx.cacheObjectContext(), true);
 
-                    val0 = (V)cctx.unwrapPortableIfNeeded(val0, !deserializePortable);
-                    key0 = (K)cctx.unwrapPortableIfNeeded(key0, !deserializePortable);
+                            val0 = (V)cctx.unwrapPortableIfNeeded(val0, !deserializePortable);
+                            key0 = (K)cctx.unwrapPortableIfNeeded(key0, !deserializePortable);
 
-                    add(new GridFinishedFuture<>(Collections.singletonMap(key0, val0)));
+                            add(new GridFinishedFuture<>(Collections.singletonMap(key0, val0)));
+                        }
+                    }
                 }
                 else {
                     if (affNode == null) {
@@ -551,19 +555,10 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                             onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache " +
                                 "(all partition nodes left the grid)."));
 
-                            return savedVers;
+                            return saved;
                         }
                     }
 
-                    GridNearCacheEntry nearEntry = allowLocRead ? near.peekExx(key) : null;
-
-                    entry = nearEntry;
-
-                    if (savedVers == null)
-                        savedVers = U.newHashMap(3);
-
-                    savedVers.put(key, nearEntry == null ? null : nearEntry.dhtVersion());
-
                     LinkedHashMap<KeyCacheObject, Boolean> keys = mapped.get(affNode);
 
                     if (keys != null && keys.containsKey(key)) {
@@ -572,10 +567,23 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                                 MAX_REMAP_CNT + " attempts (key got remapped to the same node) " +
                                 "[key=" + key + ", node=" + U.toShortString(affNode) + ", mappings=" + mapped + ']'));
 
-                            return savedVers;
+                            return saved;
                         }
                     }
 
+                    if (!cctx.affinity().localNode(key, topVer)) {
+                        GridNearCacheEntry nearEntry = entry != null ? entry : near.entryExx(key, topVer);
+
+                        nearEntry.reserveEviction();
+
+                        entry = null;
+
+                        if (saved == null)
+                            saved = U.newHashMap(3);
+
+                        saved.put(key, nearEntry);
+                    }
+
                     // Don't add reader if transaction acquires lock anyway to avoid deadlock.
                     boolean addRdr = tx == null || tx.optimistic();
 
@@ -598,21 +606,15 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                 break;
             }
             catch (GridCacheEntryRemovedException ignored) {
-                entry = allowLocRead ? near.peekEx(key) : null;
-            }
-            catch (GridCacheFilterFailedException e) {
-                if (log.isDebugEnabled())
-                    log.debug("Filter validation failed for entry: " + e);
-
-                break;
+                // Retry.
             }
             finally {
-                if (entry != null && !reload && tx == null)
+                if (entry != null && tx == null)
                     cctx.evicts().touch(entry, topVer);
             }
         }
 
-        return savedVers;
+        return saved;
     }
 
     /**
@@ -655,7 +657,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
      * @param nodeId Node id.
      * @param keys Keys.
      * @param infos Entry infos.
-     * @param savedVers Saved versions.
+     * @param savedEntries Saved entries.
      * @param topVer Topology version
      * @return Result map.
      */
@@ -663,7 +665,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
         UUID nodeId,
         Collection<KeyCacheObject> keys,
         Collection<GridCacheEntryInfo> infos,
-        Map<KeyCacheObject, GridCacheVersion> savedVers,
+        Map<KeyCacheObject, GridNearCacheEntry> savedEntries,
         AffinityTopologyVersion topVer
     ) {
         boolean empty = F.isEmpty(keys);
@@ -681,9 +683,10 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
 
                     // Entries available locally in DHT should not be loaded into near cache for reading.
                     if (!cctx.affinity().localNode(info.key(), cctx.affinity().affinityTopologyVersion())) {
-                        GridNearCacheEntry entry = cache().entryExx(info.key(), topVer);
+                        GridNearCacheEntry entry = savedEntries.get(info.key());
 
-                        GridCacheVersion saved = savedVers.get(info.key());
+                        if (entry == null)
+                            entry = cache().entryExx(info.key(), topVer);
 
                         // Load entry into cache.
                         entry.loadedValue(tx,
@@ -691,14 +694,11 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                             info.value(),
                             atomic ? info.version() : ver,
                             info.version(),
-                            saved,
                             info.ttl(),
                             info.expireTime(),
                             true,
                             topVer,
                             subjId);
-
-                        cctx.evicts().touch(entry, topVer);
                     }
 
                     CacheObject val = info.value();
@@ -706,7 +706,16 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
 
                     assert skipVals == (info.value() == null);
 
-                    cctx.addResult(map, key, val, skipVals, false, deserializePortable, false);
+                    if (needVer)
+                        versionedResult(map, key, val, info.version());
+                    else
+                        cctx.addResult(map,
+                            key,
+                            val,
+                            skipVals,
+                            keepCacheObjects,
+                            deserializePortable,
+                            false);
                 }
                 catch (GridCacheEntryRemovedException ignore) {
                     if (log.isDebugEnabled())
@@ -724,6 +733,26 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
         return map;
     }
 
+    /**
+     * @param keys Keys.
+     * @param saved Saved entries.
+     * @param topVer Topology version.
+     */
+    private void releaseEvictions(Collection<KeyCacheObject> keys,
+        Map<KeyCacheObject, GridNearCacheEntry> saved,
+        AffinityTopologyVersion topVer) {
+        for (KeyCacheObject key : keys) {
+            GridNearCacheEntry entry = saved.get(key);
+
+            if (entry != null) {
+                entry.releaseEviction();
+
+                if (tx == null)
+                    cctx.evicts().touch(entry, topVer);
+            }
+        }
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         Collection<String> futs = F.viewReadOnly(futures(), new C1<IgniteInternalFuture<?>, String>() {
@@ -763,7 +792,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
         private LinkedHashMap<KeyCacheObject, Boolean> keys;
 
         /** Saved entry versions. */
-        private Map<KeyCacheObject, GridCacheVersion> savedVers;
+        private Map<KeyCacheObject, GridNearCacheEntry> savedEntries;
 
         /** Topology version on which this future was mapped. */
         private AffinityTopologyVersion topVer;
@@ -774,18 +803,18 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
         /**
          * @param node Node.
          * @param keys Keys.
-         * @param savedVers Saved entry versions.
+         * @param savedEntries Saved entries.
          * @param topVer Topology version.
          */
         MiniFuture(
             ClusterNode node,
             LinkedHashMap<KeyCacheObject, Boolean> keys,
-            Map<KeyCacheObject, GridCacheVersion> savedVers,
+            Map<KeyCacheObject, GridNearCacheEntry> savedEntries,
             AffinityTopologyVersion topVer
         ) {
             this.node = node;
             this.keys = keys;
-            this.savedVers = savedVers;
+            this.savedEntries = savedEntries;
             this.topVer = topVer;
         }
 
@@ -821,6 +850,17 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
             onDone(e);
         }
 
+        /** {@inheritDoc} */
+        @Override public boolean onDone(@Nullable Map<K, V> res, @Nullable Throwable err) {
+            if (super.onDone(res, err)) {
+                releaseEvictions(keys.keySet(), savedEntries, topVer);
+
+                return true;
+            }
+            else
+                return false;
+        }
+
         /**
          * @param e Topology exception.
          */
@@ -915,7 +955,7 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                     }), F.t(node, keys), topVer);
 
                     // It is critical to call onDone after adding futures to compound list.
-                    onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedVers, topVer));
+                    onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedEntries, topVer));
 
                     return;
                 }
@@ -935,12 +975,12 @@ public final class GridNearGetFuture<K, V> extends GridCompoundIdentityFuture<Ma
                         }), F.t(node, keys), new AffinityTopologyVersion(readyTopVer));
 
                         // It is critical to call onDone after adding futures to compound list.
-                        onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedVers, topVer));
+                        onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedEntries, topVer));
                     }
                 });
             }
             else
-                onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedVers, topVer));
+                onDone(loadEntries(node.id(), keys.keySet(), res.entries(), savedEntries, topVer));
         }
 
         /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
index ff6375a..8482217 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
@@ -109,7 +109,6 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
      * @param ver Version.
      * @param keys Keys.
      * @param readThrough Read through flag.
-     * @param reload Reload flag.
      * @param skipVals Skip values flag. When false, only boolean values will be returned indicating whether
      *      cache entry has a value.
      * @param topVer Topology version.
@@ -125,7 +124,6 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
         GridCacheVersion ver,
         LinkedHashMap<KeyCacheObject, Boolean> keys,
         boolean readThrough,
-        boolean reload,
         @NotNull AffinityTopologyVersion topVer,
         UUID subjId,
         int taskNameHash,
@@ -145,7 +143,6 @@ public class GridNearGetRequest extends GridCacheMessage implements GridCacheDep
         this.keys = keys.keySet();
         this.flags = keys.values();
         this.readThrough = readThrough;
-        this.reload = reload;
         this.topVer = topVer;
         this.subjId = subjId;
         this.taskNameHash = taskNameHash;

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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
new file mode 100644
index 0000000..47c1d21
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
@@ -0,0 +1,930 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.near;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.cluster.ClusterTopologyException;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
+import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
+import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxMapping;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
+import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException;
+import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
+import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
+import org.apache.ignite.internal.util.GridConcurrentHashSet;
+import org.apache.ignite.internal.util.future.GridCompoundFuture;
+import org.apache.ignite.internal.util.future.GridFinishedFuture;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.C1;
+import org.apache.ignite.internal.util.typedef.CI1;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.P1;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteBiTuple;
+import org.apache.ignite.lang.IgniteClosure;
+import org.apache.ignite.lang.IgniteProductVersion;
+import org.apache.ignite.lang.IgniteReducer;
+import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
+import static org.apache.ignite.transactions.TransactionState.PREPARED;
+import static org.apache.ignite.transactions.TransactionState.PREPARING;
+
+/**
+ *
+ */
+public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptimisticTxPrepareFutureAdapter
+    implements GridCacheMvccFuture<IgniteInternalTx> {
+    /** */
+    public static final IgniteProductVersion SER_TX_SINCE = IgniteProductVersion.fromString("1.5.0");
+
+    /** */
+    @GridToStringExclude
+    private KeyLockFuture keyLockFut = new KeyLockFuture();
+
+    /** */
+    @GridToStringExclude
+    private ClientRemapFuture remapFut;
+
+    /**
+     * @param cctx Context.
+     * @param tx Transaction.
+     */
+    public GridNearOptimisticSerializableTxPrepareFuture(GridCacheSharedContext cctx, GridNearTxLocal tx) {
+        super(cctx, tx);
+
+        assert tx.optimistic() && tx.serializable() : tx;
+
+        // Should wait for all mini futures completion before finishing tx.
+        ignoreChildFailures(IgniteCheckedException.class);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate owner) {
+        if (log.isDebugEnabled())
+            log.debug("Transaction future received owner changed callback: " + entry);
+
+        if ((entry.context().isNear() || entry.context().isLocal()) && owner != null) {
+            IgniteTxEntry txEntry = tx.entry(entry.txKey());
+
+            if (txEntry != null) {
+                if (entry.context().isLocal()) {
+                    GridCacheVersion serReadVer = txEntry.serializableReadVersion();
+
+                    if (serReadVer != null) {
+                        GridCacheContext ctx = entry.context();
+
+                        while (true) {
+                            try {
+                                if (!entry.checkSerializableReadVersion(serReadVer)) {
+                                    Object key = entry.key().value(ctx.cacheObjectContext(), false);
+
+                                    IgniteTxOptimisticCheckedException err0 =
+                                        new IgniteTxOptimisticCheckedException("Failed to prepare transaction, " +
+                                            "read/write conflict [key=" + key + ", cache=" + ctx.name() + ']');
+
+                                    err.compareAndSet(null, err0);
+                                }
+
+                                break;
+                            }
+                            catch (GridCacheEntryRemovedException e) {
+                                entry = ctx.cache().entryEx(entry.key());
+
+                                txEntry.cached(entry);
+                            }
+                        }
+
+                    }
+                }
+
+                keyLockFut.onKeyLocked(entry.txKey());
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<? extends ClusterNode> nodes() {
+        return F.viewReadOnly(futures(), new IgniteClosure<IgniteInternalFuture<?>, ClusterNode>() {
+            @Nullable @Override public ClusterNode apply(IgniteInternalFuture<?> f) {
+                if (isMini(f))
+                    return ((MiniFuture)f).node();
+
+                return cctx.discovery().localNode();
+            }
+        });
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean onNodeLeft(UUID nodeId) {
+        boolean found = false;
+
+        for (IgniteInternalFuture<?> fut : futures()) {
+            if (isMini(fut)) {
+                MiniFuture f = (MiniFuture) fut;
+
+                if (f.node().id().equals(nodeId)) {
+                    ClusterTopologyCheckedException e = new ClusterTopologyCheckedException("Remote node left grid: " +
+                        nodeId);
+
+                    e.retryReadyFuture(cctx.nextAffinityReadyFuture(tx.topologyVersion()));
+
+                    f.onNodeLeft(e);
+
+                    found = true;
+                }
+            }
+        }
+
+        return found;
+    }
+
+    /**
+     * @param m Failed mapping.
+     * @param e Error.
+     */
+    private void onError(@Nullable GridDistributedTxMapping m, Throwable e) {
+        if (X.hasCause(e, ClusterTopologyCheckedException.class) || X.hasCause(e, ClusterTopologyException.class)) {
+            if (tx.onePhaseCommit()) {
+                tx.markForBackupCheck();
+
+                onComplete();
+
+                return;
+            }
+        }
+
+        if (e instanceof IgniteTxOptimisticCheckedException) {
+            if (m != null)
+                tx.removeMapping(m.node().id());
+        }
+
+        err.compareAndSet(null, e);
+
+        keyLockFut.onDone(e);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void onResult(UUID nodeId, GridNearTxPrepareResponse res) {
+        if (!isDone()) {
+            for (IgniteInternalFuture<GridNearTxPrepareResponse> fut : pending()) {
+                if (isMini(fut)) {
+                    MiniFuture f = (MiniFuture)fut;
+
+                    if (f.futureId().equals(res.miniId())) {
+                        assert f.node().id().equals(nodeId);
+
+                        f.onResult(res);
+                    }
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean onDone(IgniteInternalTx t, Throwable err) {
+        if (isDone())
+            return false;
+
+        if (err != null) {
+            this.err.compareAndSet(null, err);
+
+            keyLockFut.onDone(err);
+        }
+
+        return onComplete();
+    }
+
+    /**
+     * @param f Future.
+     * @return {@code True} if mini-future.
+     */
+    private boolean isMini(IgniteInternalFuture<?> f) {
+        return f.getClass().equals(MiniFuture.class);
+    }
+
+    /**
+     * Completeness callback.
+     *
+     * @return {@code True} if future was finished by this call.
+     */
+    private boolean onComplete() {
+        Throwable err0 = err.get();
+
+        if (err0 == null || tx.needCheckBackup())
+            tx.state(PREPARED);
+
+        if (super.onDone(tx, err0)) {
+            if (err0 != null)
+                tx.setRollbackOnly();
+
+            // Don't forget to clean up.
+            cctx.mvcc().removeFuture(this);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Initializes future.
+     *
+     * @param remap Remap flag.
+     */
+    @Override protected void prepare0(boolean remap, boolean topLocked) {
+        try {
+            boolean txStateCheck = remap ? tx.state() == PREPARING : tx.state(PREPARING);
+
+            if (!txStateCheck) {
+                if (tx.setRollbackOnly()) {
+                    if (tx.timedOut())
+                        onError(null, new IgniteTxTimeoutCheckedException("Transaction timed out and " +
+                            "was rolled back: " + this));
+                    else
+                        onError(null, new IgniteCheckedException("Invalid transaction state for prepare " +
+                            "[state=" + tx.state() + ", tx=" + this + ']'));
+                }
+                else
+                    onError(null, new IgniteTxRollbackCheckedException("Invalid transaction state for " +
+                        "prepare [state=" + tx.state() + ", tx=" + this + ']'));
+
+                return;
+            }
+
+            prepare(tx.readEntries(), tx.writeEntries(), remap, topLocked);
+
+            markInitialized();
+        }
+        catch (IgniteCheckedException e) {
+            onDone(e);
+        }
+    }
+
+    /**
+     * @param reads Read entries.
+     * @param writes Write entries.
+     * @param remap Remap flag.
+     * @param topLocked Topology locked flag.
+     * @throws IgniteCheckedException If failed.
+     */
+    @SuppressWarnings("unchecked")
+    private void prepare(
+        Iterable<IgniteTxEntry> reads,
+        Iterable<IgniteTxEntry> writes,
+        boolean remap,
+        boolean topLocked
+    ) throws IgniteCheckedException {
+        AffinityTopologyVersion topVer = tx.topologyVersion();
+
+        assert topVer.topologyVersion() > 0;
+
+        txMapping = new GridDhtTxMapping();
+
+        if (!F.isEmpty(reads) || !F.isEmpty(writes)) {
+            for (int cacheId : tx.activeCacheIds()) {
+                GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+                if (CU.affinityNodes(cacheCtx, topVer).isEmpty()) {
+                    onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
+                        "partition nodes left the grid): " + cacheCtx.name()));
+
+                    return;
+                }
+            }
+        }
+
+        Map<IgniteBiTuple<ClusterNode, Boolean>, GridDistributedTxMapping> mappings = new HashMap<>();
+
+        for (IgniteTxEntry write : writes)
+            map(write, topVer, mappings, remap, topLocked);
+
+        for (IgniteTxEntry read : reads)
+            map(read, topVer, mappings, remap, topLocked);
+
+        keyLockFut.onAllKeysAdded();
+
+        if (!remap)
+            add(keyLockFut);
+
+        if (isDone()) {
+            if (log.isDebugEnabled())
+                log.debug("Abandoning (re)map because future is done: " + this);
+
+            return;
+        }
+
+        tx.addEntryMapping(mappings.values());
+
+        cctx.mvcc().recheckPendingLocks();
+
+        tx.transactionNodes(txMapping.transactionNodes());
+
+        checkOnePhase();
+
+        for (GridDistributedTxMapping m : mappings.values()) {
+            assert !m.empty();
+
+            MiniFuture fut = new MiniFuture(m);
+
+            add(fut);
+        }
+
+        Collection<IgniteInternalFuture<?>> futs = (Collection)futures();
+
+        Iterator<IgniteInternalFuture<?>> it = futs.iterator();
+
+        while (it.hasNext()) {
+            IgniteInternalFuture<?> fut0 = it.next();
+
+            if (skipFuture(remap, fut0))
+                continue;
+
+            MiniFuture fut = (MiniFuture)fut0;
+
+            IgniteCheckedException err = prepare(fut);
+
+            if (err != null) {
+                while (it.hasNext()) {
+                    fut0 = it.next();
+
+                    if (skipFuture(remap, fut0))
+                        continue;
+
+                    fut = (MiniFuture)fut0;
+
+                    tx.removeMapping(fut.mapping().node().id());
+
+                    fut.onResult(new IgniteCheckedException("Failed to prepare transaction.", err));
+                }
+
+                break;
+            }
+        }
+
+        markInitialized();
+    }
+
+    /**
+     * @param remap Remap flag.
+     * @param fut Future.
+     * @return {@code True} if skip future during remap.
+     */
+    private boolean skipFuture(boolean remap, IgniteInternalFuture<?> fut) {
+        return !(isMini(fut)) || (remap && ((MiniFuture)fut).rcvRes.get());
+    }
+
+    /**
+     * @param fut Mini future.
+     * @return Prepare error if any.
+     */
+    @Nullable private IgniteCheckedException prepare(final MiniFuture fut) {
+        GridDistributedTxMapping m = fut.mapping();
+
+        final ClusterNode n = m.node();
+
+        GridNearTxPrepareRequest req = new GridNearTxPrepareRequest(
+            futId,
+            tx.topologyVersion(),
+            tx,
+            m.reads(),
+            m.writes(),
+            m.near(),
+            txMapping.transactionNodes(),
+            m.last(),
+            m.lastBackups(),
+            tx.onePhaseCommit(),
+            tx.needReturnValue() && tx.implicit(),
+            tx.implicitSingle(),
+            m.explicitLock(),
+            tx.subjectId(),
+            tx.taskNameHash(),
+            m.clientFirst(),
+            tx.activeCachesDeploymentEnabled());
+
+        for (IgniteTxEntry txEntry : m.writes()) {
+            if (txEntry.op() == TRANSFORM)
+                req.addDhtVersion(txEntry.txKey(), null);
+        }
+
+        // Must lock near entries separately.
+        if (m.near()) {
+            try {
+                tx.optimisticLockEntries(F.concat(false, m.writes(), m.reads()));
+
+                tx.userPrepare();
+            }
+            catch (IgniteCheckedException e) {
+                fut.onResult(e);
+
+                return e;
+            }
+        }
+
+        req.miniId(fut.futureId());
+
+        // If this is the primary node for the keys.
+        if (n.isLocal()) {
+            IgniteInternalFuture<GridNearTxPrepareResponse> prepFut = cctx.tm().txHandler().prepareTx(n.id(), tx, req);
+
+            prepFut.listen(new CI1<IgniteInternalFuture<GridNearTxPrepareResponse>>() {
+                @Override public void apply(IgniteInternalFuture<GridNearTxPrepareResponse> prepFut) {
+                    try {
+                        fut.onResult(prepFut.get());
+                    }
+                    catch (IgniteCheckedException e) {
+                        fut.onResult(e);
+                    }
+                }
+            });
+        }
+        else {
+            try {
+                cctx.io().send(n, req, tx.ioPolicy());
+            }
+            catch (ClusterTopologyCheckedException e) {
+                e.retryReadyFuture(cctx.nextAffinityReadyFuture(tx.topologyVersion()));
+
+                fut.onNodeLeft(e);
+
+                return e;
+            }
+            catch (IgniteCheckedException e) {
+                fut.onResult(e);
+
+                return e;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @param entry Transaction entry.
+     * @param topVer Topology version.
+     * @param curMapping Current mapping.
+     * @param remap Remap flag.
+     * @param topLocked Topology locked flag.
+     */
+    private void map(
+        IgniteTxEntry entry,
+        AffinityTopologyVersion topVer,
+        Map<IgniteBiTuple<ClusterNode, Boolean>, GridDistributedTxMapping> curMapping,
+        boolean remap,
+        boolean topLocked
+    ) {
+        GridCacheContext cacheCtx = entry.context();
+
+        List<ClusterNode> nodes = cacheCtx.affinity().nodes(entry.key(), topVer);
+
+        txMapping.addMapping(nodes);
+
+        ClusterNode primary = F.first(nodes);
+
+        assert primary != null;
+
+        if (log.isDebugEnabled()) {
+            log.debug("Mapped key to primary node [key=" + entry.key() +
+                ", part=" + cacheCtx.affinity().partition(entry.key()) +
+                ", primary=" + U.toShortString(primary) + ", topVer=" + topVer + ']');
+        }
+
+        if (primary.version().compareTo(SER_TX_SINCE) < 0) {
+            onDone(new IgniteCheckedException("Optimistic serializable transactions can be used only with node " +
+                "version starting from " + SER_TX_SINCE));
+
+            return;
+        }
+
+        // Must re-initialize cached entry while holding topology lock.
+        if (cacheCtx.isNear())
+            entry.cached(cacheCtx.nearTx().entryExx(entry.key(), topVer));
+        else if (!cacheCtx.isLocal())
+            entry.cached(cacheCtx.colocated().entryExx(entry.key(), topVer, true));
+        else
+            entry.cached(cacheCtx.local().entryEx(entry.key(), topVer));
+
+        if (!remap && (cacheCtx.isNear() || cacheCtx.isLocal())) {
+            if (entry.explicitVersion() == null)
+                keyLockFut.addLockKey(entry.txKey());
+        }
+
+        IgniteBiTuple<ClusterNode, Boolean> key = F.t(primary, cacheCtx.isNear());
+
+        GridDistributedTxMapping cur = curMapping.get(key);
+
+        if (cur == null) {
+            cur = new GridDistributedTxMapping(primary);
+
+            curMapping.put(key, cur);
+
+            if (primary.isLocal()) {
+                if (entry.context().isNear())
+                    tx.nearLocallyMapped(true);
+                else if (entry.context().isColocated())
+                    tx.colocatedLocallyMapped(true);
+            }
+
+            // Initialize near flag right away.
+            cur.near(cacheCtx.isNear());
+
+            cur.clientFirst(!topLocked && cctx.kernalContext().clientNode());
+
+            cur.last(true);
+        }
+
+        cur.add(entry);
+
+        if (entry.explicitVersion() != null) {
+            tx.markExplicit(primary.id());
+
+            cur.markExplicitLock();
+        }
+
+        entry.nodeId(primary.id());
+
+        if (cacheCtx.isNear()) {
+            while (true) {
+                try {
+                    GridNearCacheEntry cached = (GridNearCacheEntry)entry.cached();
+
+                    cached.dhtNodeId(tx.xidVersion(), primary.id());
+
+                    break;
+                }
+                catch (GridCacheEntryRemovedException ignore) {
+                    entry.cached(cacheCtx.near().entryEx(entry.key()));
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        Collection<String> futs = F.viewReadOnly(futures(),
+            new C1<IgniteInternalFuture<?>, String>() {
+                @Override public String apply(IgniteInternalFuture<?> f) {
+                    return "[node=" + ((MiniFuture)f).node().id() +
+                        ", loc=" + ((MiniFuture)f).node().isLocal() +
+                        ", done=" + f.isDone() + "]";
+                }
+            },
+            new P1<IgniteInternalFuture<?>>() {
+                @Override public boolean apply(IgniteInternalFuture<?> f) {
+                    return isMini(f);
+                }
+            });
+
+        return S.toString(GridNearOptimisticSerializableTxPrepareFuture.class, this,
+            "innerFuts", futs,
+            "keyLockFut", keyLockFut,
+            "tx", tx,
+            "super", super.toString());
+    }
+
+    /**
+     *
+     */
+    private class ClientRemapFuture extends GridCompoundFuture<GridNearTxPrepareResponse, Boolean> {
+        /** */
+        private boolean remap = true;
+
+        /**
+         *
+         */
+        public ClientRemapFuture() {
+            super();
+
+            reducer(new IgniteReducer<GridNearTxPrepareResponse, Boolean>() {
+                @Override public boolean collect(GridNearTxPrepareResponse res) {
+                    assert res != null;
+
+                    if (res.clientRemapVersion() == null)
+                        remap = false;
+
+                    return true;
+                }
+
+                @Override public Boolean reduce() {
+                    return remap;
+                }
+            });
+        }
+    }
+
+    /**
+     *
+     */
+    private class MiniFuture extends GridFutureAdapter<GridNearTxPrepareResponse> {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        /** */
+        private final IgniteUuid futId = IgniteUuid.randomUuid();
+
+        /** Keys. */
+        @GridToStringInclude
+        private GridDistributedTxMapping m;
+
+        /** Flag to signal some result being processed. */
+        private AtomicBoolean rcvRes = new AtomicBoolean(false);
+
+        /**
+         * @param m Mapping.
+         */
+        MiniFuture(GridDistributedTxMapping m) {
+            this.m = m;
+        }
+
+        /**
+         * @return Future ID.
+         */
+        IgniteUuid futureId() {
+            return futId;
+        }
+
+        /**
+         * @return Node ID.
+         */
+        public ClusterNode node() {
+            return m.node();
+        }
+
+        /**
+         * @return Keys.
+         */
+        public GridDistributedTxMapping mapping() {
+            return m;
+        }
+
+        /**
+         * @param e Error.
+         */
+        void onResult(Throwable e) {
+            if (rcvRes.compareAndSet(false, true)) {
+                onError(m, e);
+
+                if (log.isDebugEnabled())
+                    log.debug("Failed to get future result [fut=" + this + ", err=" + e + ']');
+
+                // Fail.
+                onDone(e);
+            }
+            else
+                U.warn(log, "Received error after another result has been processed [fut=" +
+                    GridNearOptimisticSerializableTxPrepareFuture.this + ", mini=" + this + ']', e);
+        }
+
+        /**
+         * @param e Node failure.
+         */
+        void onNodeLeft(ClusterTopologyCheckedException e) {
+            if (isDone())
+                return;
+
+            if (rcvRes.compareAndSet(false, true)) {
+                if (log.isDebugEnabled())
+                    log.debug("Remote node left grid while sending or waiting for reply (will not retry): " + this);
+
+                onError(null, e);
+
+                onDone(e);
+            }
+        }
+
+        /**
+         * @param res Result callback.
+         */
+        @SuppressWarnings("unchecked")
+        void onResult(final GridNearTxPrepareResponse res) {
+            if (isDone())
+                return;
+
+            if (rcvRes.compareAndSet(false, true)) {
+                if (res.error() != null) {
+                    // Fail the whole compound future.
+                    onError(m, res.error());
+
+                    onDone(res.error());
+                }
+                else {
+                    if (res.clientRemapVersion() != null) {
+                        assert cctx.kernalContext().clientNode();
+                        assert m.clientFirst();
+
+                        tx.removeMapping(m.node().id());
+
+                        ClientRemapFuture remapFut0 = null;
+
+                        synchronized (GridNearOptimisticSerializableTxPrepareFuture.this) {
+                            if (remapFut == null) {
+                                remapFut = new ClientRemapFuture();
+
+                                remapFut0 = remapFut;
+                            }
+                        }
+
+                        if (remapFut0 != null) {
+                            Collection<IgniteInternalFuture<?>> futs = (Collection)futures();
+
+                            for (IgniteInternalFuture<?> fut : futs) {
+                                if (isMini(fut) && fut != this)
+                                    remapFut0.add((MiniFuture)fut);
+                            }
+
+                            remapFut0.markInitialized();
+
+                            remapFut0.listen(new CI1<IgniteInternalFuture<Boolean>>() {
+                                @Override public void apply(IgniteInternalFuture<Boolean> remapFut0) {
+                                    try {
+                                        IgniteInternalFuture<?> affFut =
+                                            cctx.exchange().affinityReadyFuture(res.clientRemapVersion());
+
+                                        if (affFut == null)
+                                            affFut = new GridFinishedFuture<Object>();
+
+                                        if (remapFut.get()) {
+                                            if (log.isDebugEnabled()) {
+                                                log.debug("Will remap client tx [" +
+                                                    "fut=" + GridNearOptimisticSerializableTxPrepareFuture.this +
+                                                    ", topVer=" + res.topologyVersion() + ']');
+                                            }
+
+                                            synchronized (GridNearOptimisticSerializableTxPrepareFuture.this) {
+                                                assert remapFut0 == remapFut;
+
+                                                remapFut = null;
+                                            }
+
+                                            affFut.listen(new CI1<IgniteInternalFuture<?>>() {
+                                                @Override public void apply(IgniteInternalFuture<?> affFut) {
+                                                    try {
+                                                        affFut.get();
+
+                                                        remap(res);
+                                                    }
+                                                    catch (IgniteCheckedException e) {
+                                                        onDone(e);
+                                                    }
+                                                }
+                                            });
+                                        }
+                                        else {
+                                            ClusterTopologyCheckedException err = new ClusterTopologyCheckedException(
+                                                "Cluster topology changed while client transaction is preparing.");
+
+                                            err.retryReadyFuture(affFut);
+
+                                            onDone(err);
+                                        }
+                                    }
+                                    catch (IgniteCheckedException e) {
+                                        if (log.isDebugEnabled()) {
+                                            log.debug("Prepare failed, will not remap tx: " +
+                                                GridNearOptimisticSerializableTxPrepareFuture.this);
+                                        }
+
+                                        onDone(e);
+                                    }
+                                }
+                            });
+                        }
+                        else
+                            onDone(res);
+                    }
+                    else {
+                        onPrepareResponse(m, res);
+
+                        // Finish this mini future (need result only on client node).
+                        onDone(cctx.kernalContext().clientNode() ? res : null);
+                    }
+                }
+            }
+        }
+
+        /**
+         * @param res Response.
+         */
+        private void remap(final GridNearTxPrepareResponse res) {
+            prepareOnTopology(true, new Runnable() {
+                @Override public void run() {
+                    onDone(res);
+                }
+            });
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(MiniFuture.class, this, "done", isDone(), "cancelled", isCancelled(), "err", error());
+        }
+    }
+
+    /**
+     * Keys lock future.
+     */
+    private class KeyLockFuture extends GridFutureAdapter<GridNearTxPrepareResponse> {
+        /** */
+        @GridToStringInclude
+        private Collection<IgniteTxKey> lockKeys = new GridConcurrentHashSet<>();
+
+        /** */
+        private volatile boolean allKeysAdded;
+
+        /**
+         * @param key Key to track for locking.
+         */
+        private void addLockKey(IgniteTxKey key) {
+            assert !allKeysAdded;
+
+            lockKeys.add(key);
+        }
+
+        /**
+         * @param key Locked keys.
+         */
+        private void onKeyLocked(IgniteTxKey key) {
+            lockKeys.remove(key);
+
+            checkLocks();
+        }
+
+        /**
+         * Moves future to the ready state.
+         */
+        private void onAllKeysAdded() {
+            allKeysAdded = true;
+
+            checkLocks();
+        }
+
+        /**
+         * @return {@code True} if all locks are owned.
+         */
+        private boolean checkLocks() {
+            boolean locked = lockKeys.isEmpty();
+
+            if (locked && allKeysAdded) {
+                if (log.isDebugEnabled())
+                    log.debug("All locks are acquired for near prepare future: " + this);
+
+                onDone((GridNearTxPrepareResponse)null);
+            }
+            else {
+                if (log.isDebugEnabled())
+                    log.debug("Still waiting for locks [fut=" + this + ", keys=" + lockKeys + ']');
+            }
+
+            return locked;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(KeyLockFuture.class, this, super.toString());
+        }
+    }
+}


[28/31] ignite git commit: ignite-1607 Implemented deadlock-free optimistic serializable tx mode

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
index 0834e88..fcbf58d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
@@ -574,19 +574,42 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
                                         // Nullify explicit version so that innerSet/innerRemove will work as usual.
                                         explicitVer = null;
 
+                                    GridCacheVersion dhtVer = cached.isNear() ? writeVersion() : null;
+
                                     if (op == CREATE || op == UPDATE) {
                                         // Invalidate only for near nodes (backups cannot be invalidated).
                                         if (isSystemInvalidate() || (isInvalidate() && cacheCtx.isNear()))
-                                            cached.innerRemove(this, eventNodeId(), nodeId, false, false, true, true,
-                                                topVer, null, replicate ? DR_BACKUP : DR_NONE,
+                                            cached.innerRemove(this,
+                                                eventNodeId(),
+                                                nodeId,
+                                                false,
+                                                false,
+                                                true,
+                                                true,
+                                                topVer,
+                                                null,
+                                                replicate ? DR_BACKUP : DR_NONE,
                                                 near() ? null : explicitVer, CU.subjectId(this, cctx),
-                                                resolveTaskName());
+                                                resolveTaskName(),
+                                                dhtVer);
                                         else {
-                                            cached.innerSet(this, eventNodeId(), nodeId, val, false, false,
-                                                txEntry.ttl(), true, true, topVer, null,
-                                                replicate ? DR_BACKUP : DR_NONE, txEntry.conflictExpireTime(),
-                                                near() ? null : explicitVer, CU.subjectId(this, cctx),
-                                                resolveTaskName());
+                                            cached.innerSet(this,
+                                                eventNodeId(),
+                                                nodeId,
+                                                val,
+                                                false,
+                                                false,
+                                                txEntry.ttl(),
+                                                true,
+                                                true,
+                                                topVer,
+                                                null,
+                                                replicate ? DR_BACKUP : DR_NONE,
+                                                txEntry.conflictExpireTime(),
+                                                near() ? null : explicitVer,
+                                                CU.subjectId(this, cctx),
+                                                resolveTaskName(),
+                                                dhtVer);
 
                                             // Keep near entry up to date.
                                             if (nearCached != null) {
@@ -602,9 +625,20 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
                                         }
                                     }
                                     else if (op == DELETE) {
-                                        cached.innerRemove(this, eventNodeId(), nodeId, false, false, true, true,
-                                            topVer, null, replicate ? DR_BACKUP : DR_NONE,
-                                            near() ? null : explicitVer, CU.subjectId(this, cctx), resolveTaskName());
+                                        cached.innerRemove(this,
+                                            eventNodeId(),
+                                            nodeId,
+                                            false,
+                                            false,
+                                            true,
+                                            true,
+                                            topVer,
+                                            null,
+                                            replicate ? DR_BACKUP : DR_NONE,
+                                            near() ? null : explicitVer,
+                                            CU.subjectId(this, cctx),
+                                            resolveTaskName(),
+                                            dhtVer);
 
                                         // Keep near entry up to date.
                                         if (nearCached != null)

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheDistributedGetFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheDistributedGetFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheDistributedGetFutureAdapter.java
new file mode 100644
index 0000000..721ba4e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/CacheDistributedGetFutureAdapter.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.dht;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheFuture;
+import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
+import org.apache.ignite.internal.processors.cache.KeyCacheObject;
+import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_NEAR_GET_MAX_REMAPS;
+import static org.apache.ignite.IgniteSystemProperties.getInteger;
+
+/**
+ *
+ */
+public abstract class CacheDistributedGetFutureAdapter<K, V> extends GridCompoundIdentityFuture<Map<K, V>>
+    implements GridCacheFuture<Map<K, V>> {
+    /** Default max remap count value. */
+    public static final int DFLT_MAX_REMAP_CNT = 3;
+
+    /** Maximum number of attempts to remap key to the same primary node. */
+    protected static final int MAX_REMAP_CNT = getInteger(IGNITE_NEAR_GET_MAX_REMAPS, DFLT_MAX_REMAP_CNT);
+
+    /** Context. */
+    protected final GridCacheContext<K, V> cctx;
+
+    /** Keys. */
+    protected Collection<KeyCacheObject> keys;
+
+    /** Read through flag. */
+    protected boolean readThrough;
+
+    /** Force primary flag. */
+    protected boolean forcePrimary;
+
+    /** Future ID. */
+    protected IgniteUuid futId;
+
+    /** Trackable flag. */
+    protected boolean trackable;
+
+    /** Remap count. */
+    protected AtomicInteger remapCnt = new AtomicInteger();
+
+    /** Subject ID. */
+    protected UUID subjId;
+
+    /** Task name. */
+    protected String taskName;
+
+    /** Whether to deserialize portable objects. */
+    protected boolean deserializePortable;
+
+    /** Skip values flag. */
+    protected boolean skipVals;
+
+    /** Expiry policy. */
+    protected IgniteCacheExpiryPolicy expiryPlc;
+
+    /** Flag indicating that get should be done on a locked topology version. */
+    protected final boolean canRemap;
+
+    /** */
+    protected final boolean needVer;
+
+    /** */
+    protected final boolean keepCacheObjects;
+
+    /**
+     * @param cctx Context.
+     * @param keys Keys.
+     * @param readThrough Read through flag.
+     * @param forcePrimary If {@code true} then will force network trip to primary node even
+     *          if called on backup node.
+     * @param subjId Subject ID.
+     * @param taskName Task name.
+     * @param deserializePortable Deserialize portable flag.
+     * @param expiryPlc Expiry policy.
+     * @param skipVals Skip values flag.
+     * @param canRemap Flag indicating whether future can be remapped on a newer topology version.
+     * @param needVer If {@code true} returns values as tuples containing value and version.
+     * @param keepCacheObjects Keep cache objects flag.
+     */
+    protected CacheDistributedGetFutureAdapter(
+        GridCacheContext<K, V> cctx,
+        Collection<KeyCacheObject> keys,
+        boolean readThrough,
+        boolean forcePrimary,
+        @Nullable UUID subjId,
+        String taskName,
+        boolean deserializePortable,
+        @Nullable IgniteCacheExpiryPolicy expiryPlc,
+        boolean skipVals,
+        boolean canRemap,
+        boolean needVer,
+        boolean keepCacheObjects
+    ) {
+        super(cctx.kernalContext(), CU.<K, V>mapsReducer(keys.size()));
+
+        assert !F.isEmpty(keys);
+
+        this.cctx = cctx;
+        this.keys = keys;
+        this.readThrough = readThrough;
+        this.forcePrimary = forcePrimary;
+        this.subjId = subjId;
+        this.taskName = taskName;
+        this.deserializePortable = deserializePortable;
+        this.expiryPlc = expiryPlc;
+        this.skipVals = skipVals;
+        this.canRemap = canRemap;
+        this.needVer = needVer;
+        this.keepCacheObjects = keepCacheObjects;
+
+        futId = IgniteUuid.randomUuid();
+    }
+
+    /**
+     * @param map Result map.
+     * @param key Key.
+     * @param val Value.
+     * @param ver Version.
+     */
+    @SuppressWarnings("unchecked")
+    protected final void versionedResult(Map map, KeyCacheObject key, Object val, GridCacheVersion ver) {
+        assert needVer;
+        assert skipVals || val != null;
+        assert ver != null;
+
+        map.put(key, new T2<>(skipVals ? true : val, ver));
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
index 9d02705..bdd1140 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheAdapter.java
@@ -69,6 +69,7 @@ import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.CI2;
 import org.apache.ignite.internal.util.typedef.CI3;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -562,7 +563,7 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
 
     /**
      * This method is used internally. Use
-     * {@link #getDhtAsync(UUID, long, LinkedHashMap, boolean, boolean, AffinityTopologyVersion, UUID, int, IgniteCacheExpiryPolicy, boolean)}
+     * {@link #getDhtAsync(UUID, long, LinkedHashMap, boolean, AffinityTopologyVersion, UUID, int, IgniteCacheExpiryPolicy, boolean)}
      * method instead to retrieve DHT value.
      *
      * @param keys {@inheritDoc}
@@ -574,7 +575,6 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
         @Nullable Collection<? extends K> keys,
         boolean forcePrimary,
         boolean skipTx,
-        @Nullable GridCacheEntryEx entry,
         @Nullable UUID subjId,
         String taskName,
         boolean deserializePortable,
@@ -585,7 +585,6 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
 
         return getAllAsync(keys,
             opCtx == null || !opCtx.skipStore(),
-            null,
             /*don't check local tx. */false,
             subjId,
             taskName,
@@ -603,9 +602,10 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
      * @param taskName Task name.
      * @param expiry Expiry policy.
      * @param skipVals Skip values flag.
+     * @param canRemap Can remap flag.
      * @return Get future.
      */
-    IgniteInternalFuture<Map<KeyCacheObject, CacheObject>> getDhtAllAsync(
+    IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>> getDhtAllAsync(
         Collection<KeyCacheObject> keys,
         boolean readThrough,
         @Nullable UUID subjId,
@@ -623,7 +623,8 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
             expiry,
             skipVals,
             /*keep cache objects*/true,
-            canRemap);
+            canRemap,
+            /*need version*/true);
     }
 
     /**
@@ -631,18 +632,17 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
      * @param msgId Message ID.
      * @param keys Keys to get.
      * @param readThrough Read through flag.
-     * @param reload Reload flag.
      * @param topVer Topology version.
      * @param subjId Subject ID.
      * @param taskNameHash Task name hash code.
      * @param expiry Expiry policy.
+     * @param skipVals Skip values flag.
      * @return DHT future.
      */
     public GridDhtFuture<Collection<GridCacheEntryInfo>> getDhtAsync(UUID reader,
         long msgId,
         LinkedHashMap<KeyCacheObject, Boolean> keys,
         boolean readThrough,
-        boolean reload,
         AffinityTopologyVersion topVer,
         @Nullable UUID subjId,
         int taskNameHash,
@@ -653,7 +653,6 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
             reader,
             keys,
             readThrough,
-            reload,
             /*tx*/null,
             topVer,
             subjId,
@@ -672,6 +671,7 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
      */
     protected void processNearGetRequest(final UUID nodeId, final GridNearGetRequest req) {
         assert ctx.affinityNode();
+        assert !req.reload() : req;
 
         long ttl = req.accessTtl();
 
@@ -682,7 +682,6 @@ public abstract class GridDhtCacheAdapter<K, V> extends GridDistributedCacheAdap
                 req.messageId(),
                 req.keys(),
                 req.readThrough(),
-                req.reload(),
                 req.topologyVersion(),
                 req.subjectId(),
                 req.taskNameHash(),

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
index be2f3d3..1b2d834 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
@@ -163,6 +163,8 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
      * @param topVer Topology version.
      * @param threadId Owning thread ID.
      * @param ver Lock version.
+     * @param serOrder Version for serializable transactions ordering.
+     * @param serReadVer Optional read entry version for optimistic serializable transaction.
      * @param timeout Timeout to acquire lock.
      * @param reenter Reentry flag.
      * @param tx Tx flag.
@@ -177,10 +179,17 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
         AffinityTopologyVersion topVer,
         long threadId,
         GridCacheVersion ver,
+        @Nullable GridCacheVersion serOrder,
+        @Nullable GridCacheVersion serReadVer,
         long timeout,
         boolean reenter,
         boolean tx,
-        boolean implicitSingle) throws GridCacheEntryRemovedException, GridDistributedLockCancelledException {
+        boolean implicitSingle)
+        throws GridCacheEntryRemovedException, GridDistributedLockCancelledException
+    {
+        assert serReadVer == null || serOrder != null;
+        assert !reenter || serOrder == null;
+
         GridCacheMvccCandidate cand;
         GridCacheMvccCandidate prev;
         GridCacheMvccCandidate owner;
@@ -213,6 +222,7 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
                 threadId,
                 ver,
                 timeout,
+                serOrder,
                 reenter,
                 tx,
                 implicitSingle,
@@ -235,12 +245,12 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
 
             val = this.val;
 
-            if (mvcc != null && mvcc.isEmpty())
+            if (mvcc.isEmpty())
                 mvccExtras(null);
         }
 
         // Don't link reentries.
-        if (cand != null && !cand.reentry())
+        if (!cand.reentry())
             // Link with other candidates in the same thread.
             cctx.mvcc().addNext(cctx, cand);
 
@@ -250,7 +260,10 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean tmLock(IgniteInternalTx tx, long timeout)
+    @Override public boolean tmLock(IgniteInternalTx tx,
+        long timeout,
+        @Nullable GridCacheVersion serOrder,
+        GridCacheVersion serReadVer)
         throws GridCacheEntryRemovedException, GridDistributedLockCancelledException {
         if (tx.local()) {
             GridDhtTxLocalAdapter dhtTx = (GridDhtTxLocalAdapter)tx;
@@ -262,6 +275,8 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
                 tx.topologyVersion(),
                 tx.threadId(),
                 tx.xidVersion(),
+                serOrder,
+                serReadVer,
                 timeout,
                 /*reenter*/false,
                 /*tx*/true,

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
index a67b1de..7108da6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtGetFuture.java
@@ -17,16 +17,16 @@
 
 package org.apache.ignite.internal.processors.cache.distributed.dht;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
-import java.util.LinkedList;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheObject;
@@ -45,6 +45,7 @@ import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.lang.GridClosureException;
 import org.apache.ignite.internal.util.typedef.C2;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiClosure;
@@ -72,9 +73,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
     /** */
     private UUID reader;
 
-    /** Reload flag. */
-    private boolean reload;
-
     /** Read through flag. */
     private boolean readThrough;
 
@@ -120,7 +118,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
      * @param reader Reader.
      * @param keys Keys.
      * @param readThrough Read through flag.
-     * @param reload Reload flag.
      * @param tx Transaction.
      * @param topVer Topology version.
      * @param subjId Subject ID.
@@ -134,7 +131,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
         UUID reader,
         LinkedHashMap<KeyCacheObject, Boolean> keys,
         boolean readThrough,
-        boolean reload,
         @Nullable IgniteTxLocalEx tx,
         @NotNull AffinityTopologyVersion topVer,
         @Nullable UUID subjId,
@@ -152,7 +148,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
         this.msgId = msgId;
         this.keys = keys;
         this.readThrough = readThrough;
-        this.reload = reload;
         this.tx = tx;
         this.topVer = topVer;
         this.subjId = subjId;
@@ -291,8 +286,6 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
             return new GridFinishedFuture<Collection<GridCacheEntryInfo>>(
                 Collections.<GridCacheEntryInfo>emptyList());
 
-        final Collection<GridCacheEntryInfo> infos = new LinkedList<>();
-
         String taskName0 = cctx.kernalContext().job().currentTaskName();
 
         if (taskName0 == null)
@@ -302,89 +295,77 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
 
         GridCompoundFuture<Boolean, Boolean> txFut = null;
 
-        for (Map.Entry<KeyCacheObject, Boolean> k : keys.entrySet()) {
-            while (true) {
-                GridDhtCacheEntry e = cache().entryExx(k.getKey(), topVer);
+        ClusterNode readerNode = cctx.discovery().node(reader);
 
-                try {
-                    GridCacheEntryInfo info = e.info();
+        if (readerNode != null && !readerNode.isLocal() && cctx.discovery().cacheNearNode(readerNode, cctx.name())) {
+            for (Map.Entry<KeyCacheObject, Boolean> k : keys.entrySet()) {
+                while (true) {
+                    GridDhtCacheEntry e = cache().entryExx(k.getKey(), topVer);
 
-                    // If entry is obsolete.
-                    if (info == null)
-                        continue;
+                    try {
+                        if (e.obsolete())
+                            continue;
 
-                    boolean addReader = (!e.deleted() && k.getValue() && !skipVals);
+                        boolean addReader = (!e.deleted() && k.getValue() && !skipVals);
 
-                    if (addReader)
-                        e.unswap(false);
+                        if (addReader)
+                            e.unswap(false);
 
-                    // Register reader. If there are active transactions for this entry,
-                    // then will wait for their completion before proceeding.
-                    // TODO: GG-4003:
-                    // TODO: What if any transaction we wait for actually removes this entry?
-                    // TODO: In this case seems like we will be stuck with untracked near entry.
-                    // TODO: To fix, check that reader is contained in the list of readers once
-                    // TODO: again after the returned future completes - if not, try again.
-                    // TODO: Also, why is info read before transactions are complete, and not after?
-                    IgniteInternalFuture<Boolean> f = addReader ? e.addReader(reader, msgId, topVer) : null;
+                        // Register reader. If there are active transactions for this entry,
+                        // then will wait for their completion before proceeding.
+                        // TODO: GG-4003:
+                        // TODO: What if any transaction we wait for actually removes this entry?
+                        // TODO: In this case seems like we will be stuck with untracked near entry.
+                        // TODO: To fix, check that reader is contained in the list of readers once
+                        // TODO: again after the returned future completes - if not, try again.
+                        IgniteInternalFuture<Boolean> f = addReader ? e.addReader(reader, msgId, topVer) : null;
 
-                    if (f != null) {
-                        if (txFut == null)
-                            txFut = new GridCompoundFuture<>(CU.boolReducer());
-
-                        txFut.add(f);
-                    }
+                        if (f != null) {
+                            if (txFut == null)
+                                txFut = new GridCompoundFuture<>(CU.boolReducer());
 
-                    infos.add(info);
+                            txFut.add(f);
+                        }
 
-                    break;
-                }
-                catch (IgniteCheckedException err) {
-                    return new GridFinishedFuture<>(err);
-                }
-                catch (GridCacheEntryRemovedException ignore) {
-                    if (log.isDebugEnabled())
-                        log.debug("Got removed entry when getting a DHT value: " + e);
-                }
-                finally {
-                    cctx.evicts().touch(e, topVer);
+                        break;
+                    }
+                    catch (IgniteCheckedException err) {
+                        return new GridFinishedFuture<>(err);
+                    }
+                    catch (GridCacheEntryRemovedException ignore) {
+                        if (log.isDebugEnabled())
+                            log.debug("Got removed entry when getting a DHT value: " + e);
+                    }
+                    finally {
+                        cctx.evicts().touch(e, topVer);
+                    }
                 }
             }
-        }
 
-        if (txFut != null)
-            txFut.markInitialized();
+            if (txFut != null)
+                txFut.markInitialized();
+        }
 
-        IgniteInternalFuture<Map<KeyCacheObject, CacheObject>> fut;
+        IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>> fut;
 
         if (txFut == null || txFut.isDone()) {
-            if (reload && cctx.readThrough() && cctx.store().configured()) {
-                fut = cache().reloadAllAsync0(keys.keySet(),
-                    true,
-                    skipVals,
+            if (tx == null) {
+                fut = cache().getDhtAllAsync(
+                    keys.keySet(),
+                    readThrough,
                     subjId,
-                    taskName);
+                    taskName,
+                    expiryPlc,
+                    skipVals,
+                    /*can remap*/true);
             }
             else {
-                if (tx == null) {
-                    fut = cache().getDhtAllAsync(
-                        keys.keySet(),
-                        readThrough,
-                        subjId,
-                        taskName,
-                        expiryPlc,
-                        skipVals,
-                        /*can remap*/true);
-                }
-                else {
-                    fut = tx.getAllAsync(cctx,
-                        keys.keySet(),
-                        null,
-                        /*deserialize portable*/false,
-                        skipVals,
-                        /*keep cache objects*/true,
-                        /*skip store*/!readThrough);
-                }
+                fut = tx.getAllAsync(cctx,
+                    keys.keySet(),
+                    /*deserialize portable*/false,
+                    skipVals,
+                    /*keep cache objects*/true,
+                    /*skip store*/!readThrough);
             }
         }
         else {
@@ -393,38 +374,28 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
             // transactions to complete.
             fut = new GridEmbeddedFuture<>(
                 txFut,
-                new C2<Boolean, Exception, IgniteInternalFuture<Map<KeyCacheObject, CacheObject>>>() {
-                    @Override public IgniteInternalFuture<Map<KeyCacheObject, CacheObject>> apply(Boolean b, Exception e) {
+                new C2<Boolean, Exception, IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>>>() {
+                    @Override public IgniteInternalFuture<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>> apply(Boolean b, Exception e) {
                         if (e != null)
                             throw new GridClosureException(e);
 
-                        if (reload && cctx.readThrough() && cctx.store().configured()) {
-                            return cache().reloadAllAsync0(keys.keySet(),
-                                true,
-                                skipVals,
+                        if (tx == null) {
+                            return cache().getDhtAllAsync(
+                                keys.keySet(),
+                                readThrough,
                                 subjId,
-                                taskName);
+                                taskName,
+                                expiryPlc,
+                                skipVals,
+                                /*can remap*/true);
                         }
                         else {
-                            if (tx == null) {
-                                return cache().getDhtAllAsync(
-                                    keys.keySet(),
-                                    readThrough,
-                                    subjId,
-                                    taskName,
-                                    expiryPlc,
-                                    skipVals,
-                                    /*can remap*/true);
-                            }
-                            else {
-                                return tx.getAllAsync(cctx,
-                                    keys.keySet(),
-                                    null,
-                                    /*deserialize portable*/false,
-                                    skipVals,
-                                    /*keep cache objects*/true,
-                                    /*skip store*/!readThrough);
-                            }
+                            return tx.getAllAsync(cctx,
+                                keys.keySet(),
+                                /*deserialize portable*/false,
+                                skipVals,
+                                /*keep cache objects*/true,
+                                /*skip store*/!readThrough);
                         }
                     }
                 }
@@ -432,23 +403,29 @@ public final class GridDhtGetFuture<K, V> extends GridCompoundIdentityFuture<Col
         }
 
         return new GridEmbeddedFuture<>(
-            new C2<Map<KeyCacheObject, CacheObject>, Exception, Collection<GridCacheEntryInfo>>() {
-                @Override public Collection<GridCacheEntryInfo> apply(Map<KeyCacheObject, CacheObject> map, Exception e) {
+            new C2<Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>>, Exception, Collection<GridCacheEntryInfo>>() {
+                @Override public Collection<GridCacheEntryInfo> apply(Map<KeyCacheObject, T2<CacheObject, GridCacheVersion>> map, Exception e) {
                     if (e != null) {
                         onDone(e);
 
                         return Collections.emptyList();
                     }
                     else {
-                        for (Iterator<GridCacheEntryInfo> it = infos.iterator(); it.hasNext();) {
-                            GridCacheEntryInfo info = it.next();
+                        Collection<GridCacheEntryInfo> infos = new ArrayList<>(map.size());
 
-                            Object v = map.get(info.key());
+                        for (Map.Entry<KeyCacheObject, T2<CacheObject, GridCacheVersion>> entry : map.entrySet()) {
+                            T2<CacheObject, GridCacheVersion> val = entry.getValue();
 
-                            if (v == null)
-                                it.remove();
-                            else
-                                info.value(skipVals ? null : (CacheObject)v);
+                            assert val != null;
+
+                            GridCacheEntryInfo info = new GridCacheEntryInfo();
+
+                            info.cacheId(cctx.cacheId());
+                            info.key(entry.getKey());
+                            info.value(skipVals ? null : val.get1());
+                            info.version(val.get2());
+
+                            infos.add(info);
                         }
 
                         return infos;

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 4f3e97d..c175b0b 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
@@ -380,9 +380,10 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
      * @return Lock candidate.
      * @throws GridCacheEntryRemovedException If entry was removed.
      * @throws GridDistributedLockCancelledException If lock is canceled.
+     * @throws IgniteCheckedException If failed.
      */
     @Nullable public GridCacheMvccCandidate addEntry(GridDhtCacheEntry entry)
-        throws GridCacheEntryRemovedException, GridDistributedLockCancelledException {
+        throws GridCacheEntryRemovedException, GridDistributedLockCancelledException, IgniteCheckedException {
         if (log.isDebugEnabled())
             log.debug("Adding entry: " + entry);
 
@@ -400,6 +401,8 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
             topVer,
             threadId,
             lockVer,
+            null,
+            null,
             timeout,
             /*reenter*/false,
             inTx(),

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 c09a611..4ce4759 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
@@ -672,9 +672,9 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
                         if (log.isDebugEnabled())
                             log.debug("Got removed entry when adding lock (will retry): " + entry);
                     }
-                    catch (GridDistributedLockCancelledException e) {
+                    catch (IgniteCheckedException | GridDistributedLockCancelledException e) {
                         if (log.isDebugEnabled())
-                            log.debug("Got lock request for cancelled lock (will fail): " + entry);
+                            log.debug("Failed to add entry [err=" + e + ", entry=" + entry + ']');
 
                         return new GridDhtFinishedFuture<>(e);
                     }
@@ -1106,62 +1106,55 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
                             if (tx == null || !tx.isRollbackOnly()) {
                                 GridCacheVersion dhtVer = req.dhtVersion(i);
 
-                                try {
-                                    GridCacheVersion ver = e.version();
-
-                                    boolean ret = req.returnValue(i) || dhtVer == null || !dhtVer.equals(ver);
-
-                                    CacheObject val = null;
-
-                                    if (ret)
-                                        val = e.innerGet(tx,
-                                            /*swap*/true,
-                                            /*read-through*/false,
-                                            /*fail-fast.*/false,
-                                            /*unmarshal*/false,
-                                            /*update-metrics*/true,
-                                            /*event notification*/req.returnValue(i),
-                                            /*temporary*/false,
-                                            CU.subjectId(tx, ctx.shared()),
-                                            null,
-                                            tx != null ? tx.resolveTaskName() : null,
-                                            null);
-
-                                    assert e.lockedBy(mappedVer) ||
-                                        (ctx.mvcc().isRemoved(e.context(), mappedVer) && req.timeout() > 0) :
-                                        "Entry does not own lock for tx [locNodeId=" + ctx.localNodeId() +
-                                            ", entry=" + e +
-                                            ", mappedVer=" + mappedVer + ", ver=" + ver +
-                                            ", tx=" + tx + ", req=" + req +
-                                            ", err=" + err + ']';
-
-                                    boolean filterPassed = false;
-
-                                    if (tx != null && tx.onePhaseCommit()) {
-                                        IgniteTxEntry writeEntry = tx.entry(ctx.txKey(e.key()));
-
-                                        assert writeEntry != null :
-                                            "Missing tx entry for locked cache entry: " + e;
-
-                                        filterPassed = writeEntry.filtersPassed();
-                                    }
-
-                                    if (ret && val == null)
-                                        val = e.valueBytes(null);
-
-                                    // We include values into response since they are required for local
-                                    // calls and won't be serialized. We are also including DHT version.
-                                    res.addValueBytes(
-                                        ret ? val : null,
-                                        filterPassed,
-                                        ver,
-                                        mappedVer);
-                                }
-                                catch (GridCacheFilterFailedException ex) {
-                                    assert false : "Filter should never fail if fail-fast is false.";
+                                GridCacheVersion ver = e.version();
+
+                                boolean ret = req.returnValue(i) || dhtVer == null || !dhtVer.equals(ver);
+
+                                CacheObject val = null;
+
+                                if (ret)
+                                    val = e.innerGet(tx,
+                                        /*swap*/true,
+                                        /*read-through*/false,
+                                        /*fail-fast.*/false,
+                                        /*unmarshal*/false,
+                                        /*update-metrics*/true,
+                                        /*event notification*/req.returnValue(i),
+                                        /*temporary*/false,
+                                        CU.subjectId(tx, ctx.shared()),
+                                        null,
+                                        tx != null ? tx.resolveTaskName() : null,
+                                        null);
+
+                                assert e.lockedBy(mappedVer) ||
+                                    (ctx.mvcc().isRemoved(e.context(), mappedVer) && req.timeout() > 0) :
+                                    "Entry does not own lock for tx [locNodeId=" + ctx.localNodeId() +
+                                        ", entry=" + e +
+                                        ", mappedVer=" + mappedVer + ", ver=" + ver +
+                                        ", tx=" + tx + ", req=" + req +
+                                        ", err=" + err + ']';
+
+                                boolean filterPassed = false;
 
-                                    ex.printStackTrace();
+                                if (tx != null && tx.onePhaseCommit()) {
+                                    IgniteTxEntry writeEntry = tx.entry(ctx.txKey(e.key()));
+
+                                    assert writeEntry != null :
+                                        "Missing tx entry for locked cache entry: " + e;
+
+                                    filterPassed = writeEntry.filtersPassed();
                                 }
+
+                                if (ret && val == null)
+                                    val = e.valueBytes(null);
+
+                                // We include values into response since they are required for local
+                                // calls and won't be serialized. We are also including DHT version.
+                                res.addValueBytes(
+                                    ret ? val : null,
+                                    filterPassed,
+                                    ver,
+                                    mappedVer);
                             }
                             else {
                                 // We include values into response since they are required for local

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
index 4f8469f..44f34aa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
@@ -595,7 +595,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
                 if (finish(false) || state() == UNKNOWN)
                     fut.finish();
                 else
-                    fut.onError(new IgniteCheckedException("Failed to commit transaction: " + CU.txString(this)));
+                    fut.onError(new IgniteCheckedException("Failed to rollback transaction: " + CU.txString(this)));
             }
             catch (IgniteTxOptimisticCheckedException e) {
                 if (log.isDebugEnabled())
@@ -627,7 +627,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
                         if (finish(false) || state() == UNKNOWN)
                             fut.finish();
                         else
-                            fut.onError(new IgniteCheckedException("Failed to commit transaction: " +
+                            fut.onError(new IgniteCheckedException("Failed to rollback transaction: " +
                                 CU.txString(GridDhtTxLocal.this)));
 
                     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 a15a334..d806801 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
@@ -42,7 +42,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException;
 import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
 import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture;
 import org.apache.ignite.internal.processors.cache.GridCacheOperation;
@@ -57,6 +56,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.processors.dr.GridDrType;
+import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException;
 import org.apache.ignite.internal.util.F0;
 import org.apache.ignite.internal.util.GridConcurrentHashSet;
 import org.apache.ignite.internal.util.GridLeanSet;
@@ -429,9 +429,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
             catch (GridCacheEntryRemovedException e) {
                 assert false : "Got entry removed exception while holding transactional lock on entry: " + e;
             }
-            catch (GridCacheFilterFailedException e) {
-                assert false : "Got filter failed exception with fail fast false " + e;
-            }
         }
     }
 
@@ -472,8 +469,18 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
         if (log.isDebugEnabled())
             log.debug("Marking all local candidates as ready: " + this);
 
-        Iterable<IgniteTxEntry> checkEntries = writes;
+        readyLocks(writes);
+
+        if (tx.serializable() && tx.optimistic())
+            readyLocks(reads);
 
+        locksReady = true;
+    }
+
+    /**
+     * @param checkEntries Entries.
+     */
+    private void readyLocks(Iterable<IgniteTxEntry> checkEntries) {
         for (IgniteTxEntry txEntry : checkEntries) {
             GridCacheContext cacheCtx = txEntry.context();
 
@@ -513,8 +520,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
                 }
             }
         }
-
-        locksReady = true;
     }
 
     /**
@@ -813,12 +818,19 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
         this.writes = writes;
         this.txNodes = txNodes;
 
-        if (!F.isEmpty(writes)) {
+        boolean ser = tx.serializable() && tx.optimistic();
+
+        if (!F.isEmpty(writes) || (ser && !F.isEmpty(reads))) {
             Map<Integer, Collection<KeyCacheObject>> forceKeys = null;
 
             for (IgniteTxEntry entry : writes)
                 forceKeys = checkNeedRebalanceKeys(entry, forceKeys);
 
+            if (ser) {
+                for (IgniteTxEntry entry : reads)
+                    forceKeys = checkNeedRebalanceKeys(entry, forceKeys);
+            }
+
             forceKeysFut = forceRebalanceKeys(forceKeys);
         }
 
@@ -847,7 +859,10 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
         IgniteTxEntry e,
         Map<Integer, Collection<KeyCacheObject>> map
     ) {
-        if (retVal || !F.isEmpty(e.entryProcessors()) || !F.isEmpty(e.filters())) {
+        if (retVal ||
+            !F.isEmpty(e.entryProcessors()) ||
+            !F.isEmpty(e.filters()) ||
+            e.serializableReadVersion() != null) {
             if (map == null)
                 map = new HashMap<>();
 
@@ -906,10 +921,86 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
     }
 
     /**
+     * @param entries Entries.
+     * @return Not null exception if version check failed.
+     * @throws IgniteCheckedException If failed.
+     */
+    @Nullable private IgniteCheckedException checkReadConflict(Iterable<IgniteTxEntry> entries)
+        throws IgniteCheckedException {
+        try {
+            for (IgniteTxEntry entry : entries) {
+                GridCacheVersion serReadVer = entry.serializableReadVersion();
+
+                if (serReadVer != null) {
+                    entry.cached().unswap();
+
+                    if (!entry.cached().checkSerializableReadVersion(serReadVer))
+                        return versionCheckError(entry);
+                }
+            }
+        }
+        catch (GridCacheEntryRemovedException e) {
+            assert false : "Got removed exception on entry with dht local candidate: " + entries;
+        }
+
+        return null;
+    }
+
+    /**
+     * @param entry Entry.
+     * @return Optimistic version check error.
+     */
+    private IgniteTxOptimisticCheckedException versionCheckError(IgniteTxEntry entry) {
+        GridCacheContext cctx = entry.context();
+
+        return new IgniteTxOptimisticCheckedException("Failed to prepare transaction, " +
+            "read/write conflict [key=" + entry.key().value(cctx.cacheObjectContext(), false) +
+            ", cache=" + cctx.name() + ']');
+    }
+
+    /**
      *
      */
     private void prepare0() {
         try {
+            if (tx.serializable() && tx.optimistic()) {
+                IgniteCheckedException err0;
+
+                try {
+                    err0 = checkReadConflict(writes);
+
+                    if (err0 == null)
+                        err0 = checkReadConflict(reads);
+                }
+                catch (IgniteCheckedException e) {
+                    U.error(log, "Failed to check entry version: " + e, e);
+
+                    err0 = e;
+                }
+
+                if (err0 != null) {
+                    err.compareAndSet(null, err0);
+
+                    final GridNearTxPrepareResponse res = createPrepareResponse();
+
+                    tx.rollbackAsync().listen(new CI1<IgniteInternalFuture<IgniteInternalTx>>() {
+                        @Override public void apply(IgniteInternalFuture<IgniteInternalTx> fut) {
+                            if (GridDhtTxPrepareFuture.super.onDone(res, res.error())) {
+                                try {
+                                    if (replied.compareAndSet(false, true))
+                                        sendPrepareResponse(res);
+                                }
+                                catch (IgniteCheckedException e) {
+                                    U.error(log, "Failed to send prepare response for transaction: " + tx, e);
+                                }
+                            }
+                        }
+                    });
+
+                    return;
+                }
+            }
+
             // We are holding transaction-level locks for entries here, so we can get next write version.
             onEntriesLocked();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
index a68e834..febe9ba 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridPartitionedGetFuture.java
@@ -24,11 +24,9 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
@@ -39,8 +37,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFuture;
 import org.apache.ignite.internal.processors.cache.GridCacheMessage;
 import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
 import org.apache.ignite.internal.processors.cache.KeyCacheObject;
@@ -49,7 +45,6 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetR
 import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.util.GridLeanMap;
-import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -58,6 +53,7 @@ import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.CIX1;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.P1;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -65,83 +61,30 @@ import org.apache.ignite.lang.IgniteClosure;
 import org.apache.ignite.lang.IgniteUuid;
 import org.jetbrains.annotations.Nullable;
 
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_NEAR_GET_MAX_REMAPS;
-
 /**
  * Colocated get future.
  */
-public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<Map<K, V>>
-    implements GridCacheFuture<Map<K, V>> {
+public class GridPartitionedGetFuture<K, V> extends CacheDistributedGetFutureAdapter<K, V> {
     /** */
     private static final long serialVersionUID = 0L;
 
-    /** Default max remap count value. */
-    public static final int DFLT_MAX_REMAP_CNT = 3;
-
     /** Logger reference. */
     private static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
 
     /** Logger. */
     private static IgniteLogger log;
 
-    /** Maximum number of attempts to remap key to the same primary node. */
-    private static final int MAX_REMAP_CNT = IgniteSystemProperties.getInteger(IGNITE_NEAR_GET_MAX_REMAPS,
-        DFLT_MAX_REMAP_CNT);
-
-    /** Context. */
-    private final GridCacheContext<K, V> cctx;
-
-    /** Keys. */
-    private Collection<KeyCacheObject> keys;
-
     /** Topology version. */
     private AffinityTopologyVersion topVer;
 
-    /** Reload flag. */
-    private boolean reload;
-
-    /** Read-through flag. */
-    private boolean readThrough;
-
-    /** Force primary flag. */
-    private boolean forcePrimary;
-
-    /** Future ID. */
-    private IgniteUuid futId;
-
     /** Version. */
     private GridCacheVersion ver;
 
-    /** Trackable flag. */
-    private volatile boolean trackable;
-
-    /** Remap count. */
-    private AtomicInteger remapCnt = new AtomicInteger();
-
-    /** Subject ID. */
-    private UUID subjId;
-
-    /** Task name. */
-    private String taskName;
-
-    /** Whether to deserialize portable objects. */
-    private boolean deserializePortable;
-
-    /** Expiry policy. */
-    private IgniteCacheExpiryPolicy expiryPlc;
-
-    /** Skip values flag. */
-    private boolean skipVals;
-
-    /** Flag indicating whether future can be remapped on a newer topology version. */
-    private final boolean canRemap;
-
     /**
      * @param cctx Context.
      * @param keys Keys.
      * @param topVer Topology version.
      * @param readThrough Read through flag.
-     * @param reload Reload flag.
      * @param forcePrimary If {@code true} then will force network trip to primary node even
      *          if called on backup node.
      * @param subjId Subject ID.
@@ -149,39 +92,39 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
      * @param deserializePortable Deserialize portable flag.
      * @param expiryPlc Expiry policy.
      * @param skipVals Skip values flag.
+     * @param canRemap Flag indicating whether future can be remapped on a newer topology version.
+     * @param needVer If {@code true} returns values as tuples containing value and version.
+     * @param keepCacheObjects Keep cache objects flag.
      */
     public GridPartitionedGetFuture(
         GridCacheContext<K, V> cctx,
         Collection<KeyCacheObject> keys,
         AffinityTopologyVersion topVer,
         boolean readThrough,
-        boolean reload,
         boolean forcePrimary,
         @Nullable UUID subjId,
         String taskName,
         boolean deserializePortable,
         @Nullable IgniteCacheExpiryPolicy expiryPlc,
         boolean skipVals,
-        boolean canRemap
+        boolean canRemap,
+        boolean needVer,
+        boolean keepCacheObjects
     ) {
-        super(cctx.kernalContext(), CU.<K, V>mapsReducer(keys.size()));
-
-        assert !F.isEmpty(keys);
+        super(cctx,
+            keys,
+            readThrough,
+            forcePrimary,
+            subjId,
+            taskName,
+            deserializePortable,
+            expiryPlc,
+            skipVals,
+            canRemap,
+            needVer,
+            keepCacheObjects);
 
-        this.cctx = cctx;
-        this.keys = keys;
         this.topVer = topVer;
-        this.readThrough = readThrough;
-        this.reload = reload;
-        this.forcePrimary = forcePrimary;
-        this.subjId = subjId;
-        this.deserializePortable = deserializePortable;
-        this.taskName = taskName;
-        this.expiryPlc = expiryPlc;
-        this.skipVals = skipVals;
-        this.canRemap = canRemap;
-
-        futId = IgniteUuid.randomUuid();
 
         ver = cctx.versions().next();
 
@@ -351,7 +294,6 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
                         -1,
                         mappedKeys,
                         readThrough,
-                        reload,
                         topVer,
                         subjId,
                         taskName == null ? 0 : taskName.hashCode(),
@@ -404,7 +346,6 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
                     ver,
                     mappedKeys,
                     readThrough,
-                    reload,
                     topVer,
                     subjId,
                     taskName == null ? 0 : taskName.hashCode(),
@@ -452,10 +393,10 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
         boolean allowLocRead = !forcePrimary || cctx.affinity().primary(cctx.localNode(), key, topVer);
 
         while (true) {
-            GridCacheEntryEx entry = null;
+            GridCacheEntryEx entry;
 
             try {
-                if (!reload && allowLocRead) {
+                if (allowLocRead) {
                     try {
                         entry = colocated.context().isSwapOrOffheapEnabled() ? colocated.entryEx(key) :
                             colocated.peekEx(key);
@@ -464,18 +405,40 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
                         if (entry != null) {
                             boolean isNew = entry.isNewLocked();
 
-                            CacheObject v = entry.innerGet(null,
-                                /*swap*/true,
-                                /*read-through*/false,
-                                /*fail-fast*/true,
-                                /*unmarshal*/true,
-                                /**update-metrics*/false,
-                                /*event*/!skipVals,
-                                /*temporary*/false,
-                                subjId,
-                                null,
-                                taskName,
-                                expiryPlc);
+                            CacheObject v = null;
+                            GridCacheVersion ver = null;
+
+                            if (needVer) {
+                                T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                                    null,
+                                    /*swap*/true,
+                                    /*unmarshal*/true,
+                                    /**update-metrics*/false,
+                                    /*event*/!skipVals,
+                                    subjId,
+                                    null,
+                                    taskName,
+                                    expiryPlc);
+
+                                if (res != null) {
+                                    v = res.get1();
+                                    ver = res.get2();
+                                }
+                            }
+                            else {
+                                v = entry.innerGet(null,
+                                    /*swap*/true,
+                                    /*read-through*/false,
+                                    /*fail-fast*/true,
+                                    /*unmarshal*/true,
+                                    /**update-metrics*/false,
+                                    /*event*/!skipVals,
+                                    /*temporary*/false,
+                                    subjId,
+                                    null,
+                                    taskName,
+                                    expiryPlc);
+                            }
 
                             colocated.context().evicts().touch(entry, topVer);
 
@@ -485,7 +448,16 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
                                     colocated.removeIfObsolete(key);
                             }
                             else {
-                                cctx.addResult(locVals, key, v, skipVals, false, deserializePortable, true);
+                                if (needVer)
+                                    versionedResult(locVals, key, v, ver);
+                                else
+                                    cctx.addResult(locVals,
+                                        key,
+                                        v,
+                                        skipVals,
+                                        keepCacheObjects,
+                                        deserializePortable,
+                                        true);
 
                                 return false;
                             }
@@ -536,14 +508,6 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
             catch (GridCacheEntryRemovedException ignored) {
                 // No-op, will retry.
             }
-            catch (GridCacheFilterFailedException e) {
-                if (log.isDebugEnabled())
-                    log.debug("Filter validation failed for entry: " + e);
-
-                colocated.context().evicts().touch(entry, topVer);
-
-                break;
-            }
         }
 
         return remote;
@@ -591,7 +555,16 @@ public class GridPartitionedGetFuture<K, V> extends GridCompoundIdentityFuture<M
             for (GridCacheEntryInfo info : infos) {
                 assert skipVals == (info.value() == null);
 
-                cctx.addResult(map, info.key(), info.value(), skipVals, false, deserializePortable, false);
+                if (needVer)
+                    versionedResult(map, info.key(), info.value(), info.version());
+                else
+                    cctx.addResult(map,
+                        info.key(),
+                        info.value(),
+                        skipVals,
+                        keepCacheObjects,
+                        deserializePortable,
+                        false);
             }
 
             return map;

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 cba6872..4cd9e84 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
@@ -306,7 +306,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
         @Nullable final Collection<? extends K> keys,
         final boolean forcePrimary,
         boolean skipTx,
-        @Nullable final GridCacheEntryEx entry,
         @Nullable UUID subjId,
         final String taskName,
         final boolean deserializePortable,
@@ -334,7 +333,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
         return asyncOp(new CO<IgniteInternalFuture<Map<K, V>>>() {
             @Override public IgniteInternalFuture<Map<K, V>> apply() {
                 return getAllAsync0(ctx.cacheKeysView(keys),
-                    false,
                     forcePrimary,
                     subjId0,
                     taskName,
@@ -920,7 +918,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
      * Entry point to all public API get methods.
      *
      * @param keys Keys to remove.
-     * @param reload Reload flag.
      * @param forcePrimary Force primary flag.
      * @param subjId Subject ID.
      * @param taskName Task name.
@@ -931,7 +928,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
      * @return Get future.
      */
     private IgniteInternalFuture<Map<K, V>> getAllAsync0(@Nullable Collection<KeyCacheObject> keys,
-        boolean reload,
         boolean forcePrimary,
         UUID subjId,
         String taskName,
@@ -947,7 +943,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
         final IgniteCacheExpiryPolicy expiry = skipVals ? null : expiryPolicy(expiryPlc);
 
         // Optimisation: try to resolve value locally and escape 'get future' creation.
-        if (!reload && !forcePrimary) {
+        if (!forcePrimary) {
             Map<K, V> locVals = U.newHashMap(keys.size());
 
             boolean success = true;
@@ -997,10 +993,6 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
                     catch (GridCacheEntryRemovedException ignored) {
                         // No-op, retry.
                     }
-                    catch (GridCacheFilterFailedException ignored) {
-                        // No-op, skip the key.
-                        break;
-                    }
                     catch (GridDhtInvalidPartitionException ignored) {
                         success = false;
 
@@ -1036,14 +1028,15 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
             keys,
             topVer,
             !skipStore,
-            reload,
             forcePrimary,
             subjId,
             taskName,
             deserializePortable,
             expiry,
             skipVals,
-            canRemap);
+            canRemap,
+            false,
+            false);
 
         fut.init();
 
@@ -1663,6 +1656,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
 
                     if (idx != null) {
                         GridDhtCacheEntry entry = entries.get(idx);
+
                         try {
                             GridCacheVersion ver = entry.version();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
index 6d69198..f03b461 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
@@ -36,7 +36,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheConcurrentMap;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
 import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException;
 import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException;
 import org.apache.ignite.internal.processors.cache.GridCacheMapEntry;
 import org.apache.ignite.internal.processors.cache.GridCacheMapEntryFactory;
@@ -68,6 +67,7 @@ import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.typedef.C2;
 import org.apache.ignite.internal.util.typedef.CI2;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -188,7 +188,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
         @Nullable final Collection<? extends K> keys,
         boolean forcePrimary,
         boolean skipTx,
-        @Nullable final GridCacheEntryEx entry,
         @Nullable UUID subjId,
         String taskName,
         final boolean deserializePortable,
@@ -212,7 +211,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
                 @Override public IgniteInternalFuture<Map<K, V>> op(IgniteTxLocalAdapter tx) {
                     return tx.getAllAsync(ctx,
                         ctx.cacheKeysView(keys),
-                        entry,
                         deserializePortable,
                         skipVals,
                         false,
@@ -230,7 +228,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
         return loadAsync(
             ctx.cacheKeysView(keys),
             opCtx == null || !opCtx.skipStore(),
-            false,
             forcePrimary,
             topVer,
             subjId,
@@ -257,7 +254,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
     /**
      * @param keys Keys to load.
      * @param readThrough Read through flag.
-     * @param reload Reload flag.
      * @param forcePrimary Force get from primary node flag.
      * @param topVer Topology version.
      * @param subjId Subject ID.
@@ -265,12 +261,12 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
      * @param deserializePortable Deserialize portable flag.
      * @param expiryPlc Expiry policy.
      * @param skipVals Skip values flag.
+     * @param canRemap Can remap flag.
      * @return Loaded values.
      */
     public IgniteInternalFuture<Map<K, V>> loadAsync(
         @Nullable Collection<KeyCacheObject> keys,
         boolean readThrough,
-        boolean reload,
         boolean forcePrimary,
         AffinityTopologyVersion topVer,
         @Nullable UUID subjId,
@@ -278,7 +274,45 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
         boolean deserializePortable,
         @Nullable IgniteCacheExpiryPolicy expiryPlc,
         boolean skipVals,
-        boolean canRemap
+        boolean canRemap) {
+        return loadAsync(keys,
+            readThrough,
+            forcePrimary,
+            topVer, subjId,
+            taskName,
+            deserializePortable,
+            expiryPlc,
+            skipVals,
+            canRemap,
+            false,
+            false);
+    }
+
+    /**
+     * @param keys Keys to load.
+     * @param readThrough Read through flag.
+     * @param forcePrimary Force get from primary node flag.
+     * @param topVer Topology version.
+     * @param subjId Subject ID.
+     * @param taskName Task name.
+     * @param deserializePortable Deserialize portable flag.
+     * @param expiryPlc Expiry policy.
+     * @param skipVals Skip values flag.
+     * @return Loaded values.
+     */
+    public IgniteInternalFuture<Map<K, V>> loadAsync(
+        @Nullable Collection<KeyCacheObject> keys,
+        boolean readThrough,
+        boolean forcePrimary,
+        AffinityTopologyVersion topVer,
+        @Nullable UUID subjId,
+        String taskName,
+        boolean deserializePortable,
+        @Nullable IgniteCacheExpiryPolicy expiryPlc,
+        boolean skipVals,
+        boolean canRemap,
+        boolean needVer,
+        boolean keepCacheObj
     ) {
         if (keys == null || keys.isEmpty())
             return new GridFinishedFuture<>(Collections.<K, V>emptyMap());
@@ -287,8 +321,8 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
             expiryPlc = expiryPolicy(null);
 
         // Optimisation: try to resolve value locally and escape 'get future' creation.
-        if (!reload && !forcePrimary) {
-            Map<K, V> locVals = U.newHashMap(keys.size());
+        if (!forcePrimary) {
+            Map<K, V> locVals = null;
 
             boolean success = true;
 
@@ -304,18 +338,40 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
                         if (entry != null) {
                             boolean isNew = entry.isNewLocked();
 
-                            CacheObject v = entry.innerGet(null,
-                                /*swap*/true,
-                                /*read-through*/false,
-                                /*fail-fast*/true,
-                                /*unmarshal*/true,
-                                /**update-metrics*/false,
-                                /*event*/!skipVals,
-                                /*temporary*/false,
-                                subjId,
-                                null,
-                                taskName,
-                                expiryPlc);
+                            CacheObject v = null;
+                            GridCacheVersion ver = null;
+
+                            if (needVer) {
+                                T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(
+                                    null,
+                                    /*swap*/true,
+                                    /*unmarshal*/true,
+                                    /**update-metrics*/false,
+                                    /*event*/!skipVals,
+                                    subjId,
+                                    null,
+                                    taskName,
+                                    expiryPlc);
+
+                                if (res != null) {
+                                    v = res.get1();
+                                    ver = res.get2();
+                                }
+                            }
+                            else {
+                                v = entry.innerGet(null,
+                                    /*swap*/true,
+                                    /*read-through*/false,
+                                    /*fail-fast*/true,
+                                    /*unmarshal*/true,
+                                    /**update-metrics*/false,
+                                    /*event*/!skipVals,
+                                    /*temporary*/false,
+                                    subjId,
+                                    null,
+                                    taskName,
+                                    expiryPlc);
+                            }
 
                             // Entry was not in memory or in swap, so we remove it from cache.
                             if (v == null) {
@@ -326,8 +382,22 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
 
                                 success = false;
                             }
-                            else
-                                ctx.addResult(locVals, key, v, skipVals, false, deserializePortable, true);
+                            else {
+                                if (locVals == null)
+                                    locVals = U.newHashMap(keys.size());
+
+                                if (needVer)
+                                    locVals.put((K)key, (V)new T2<>((Object)(skipVals ? true : v), ver));
+                                else {
+                                    ctx.addResult(locVals,
+                                        key,
+                                        v,
+                                        skipVals,
+                                        keepCacheObj,
+                                        deserializePortable,
+                                        true);
+                                }
+                            }
                         }
                         else
                             success = false;
@@ -337,10 +407,6 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
                     catch (GridCacheEntryRemovedException ignored) {
                         // No-op, retry.
                     }
-                    catch (GridCacheFilterFailedException ignored) {
-                        // No-op, skip the key.
-                        break;
-                    }
                     catch (GridDhtInvalidPartitionException ignored) {
                         success = false;
 
@@ -377,14 +443,15 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
             keys,
             topVer,
             readThrough,
-            reload,
             forcePrimary,
             subjId,
             taskName,
             deserializePortable,
             expiryPlc,
             skipVals,
-            canRemap);
+            canRemap,
+            needVer,
+            keepCacheObj);
 
         fut.init();
 
@@ -803,10 +870,9 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
                         if (log.isDebugEnabled())
                             log.debug("Got removed entry when adding lock (will retry): " + entry);
                     }
-                    catch (GridDistributedLockCancelledException e) {
+                    catch (IgniteCheckedException | GridDistributedLockCancelledException e) {
                         if (log.isDebugEnabled())
-                            log.debug("Got lock request for cancelled lock (will ignore): " +
-                                entry);
+                            log.debug("Failed to add entry [err=" + e + ", entry=" + entry + ']');
 
                         fut.onError(e);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 53c2b63..365b46b 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
@@ -323,7 +323,8 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
                     inTx(),
                     inTx() && tx.implicitSingle(),
                     false,
-                    false);
+                    false,
+                    null);
 
                 cand.topologyVersion(topVer.get());
             }
@@ -342,7 +343,8 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
                     inTx(),
                     inTx() && tx.implicitSingle(),
                     false,
-                    false);
+                    false,
+                    null);
 
                 cand.topologyVersion(topVer.get());
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java
index 82054d9..1bf03a9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearAtomicCache.java
@@ -385,7 +385,6 @@ public class GridNearAtomicCache<K, V> extends GridNearCacheAdapter<K, V> {
         @Nullable Collection<? extends K> keys,
         boolean forcePrimary,
         boolean skipTx,
-        @Nullable GridCacheEntryEx entry,
         @Nullable UUID subjId,
         String taskName,
         boolean deserializePortable,
@@ -406,7 +405,6 @@ public class GridNearAtomicCache<K, V> extends GridNearCacheAdapter<K, V> {
 
         return loadAsync(null,
             ctx.cacheKeysView(keys),
-            false,
             forcePrimary,
             subjId,
             taskName,


[02/31] ignite git commit: review

Posted by ra...@apache.org.
review


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

Branch: refs/heads/ignite-1790
Commit: 056490d239c46a3950234ce7ea9afc4b203a00c3
Parents: cb0d432
Author: Yakov Zhdanov <yz...@gridgain.com>
Authored: Thu Oct 22 13:52:43 2015 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Thu Oct 22 13:52:43 2015 +0300

----------------------------------------------------------------------
 .../apache/ignite/stream/mqtt/MqttStreamer.java | 125 ++++++++++---------
 .../stream/mqtt/IgniteMqttStreamerTest.java     |  71 +++++------
 .../mqtt/IgniteMqttStreamerTestSuite.java       |   2 -
 3 files changed, 102 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/056490d2/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
index 39d8d6e..a075695 100644
--- a/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
+++ b/modules/mqtt/src/main/java/org/apache/ignite/stream/mqtt/MqttStreamer.java
@@ -74,10 +74,8 @@ import org.eclipse.paho.client.mqttv3.MqttMessage;
  * {@link #setConnectOptions(MqttConnectOptions)} setter.
  *
  * @see <a href="https://github.com/rholder/guava-retrying">guava-retrying library</a>
- *
  */
 public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> implements MqttCallback {
-
     /** Logger. */
     private IgniteLogger log;
 
@@ -96,8 +94,10 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     /** The topics to subscribe to, if many. */
     private List<String> topics;
 
-    /** The qualities of service to use for multiple topic subscriptions. If specified, it must contain the same
-     *  number of elements as {@link #topics}. */
+    /**
+     * The qualities of service to use for multiple topic subscriptions. If specified, it must contain the same
+     * number of elements as {@link #topics}.
+     */
     private List<Integer> qualitiesOfService;
 
     /** The MQTT client ID (optional). */
@@ -118,8 +118,10 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     /** If disconnecting forcibly, the timeout. */
     private Integer disconnectForciblyTimeout;
 
-    /** The strategy to determine how long to wait between retry attempts. By default, this streamer uses a
-     *  Fibonacci-based strategy. */
+    /**
+     * The strategy to determine how long to wait between retry attempts. By default, this streamer uses a
+     * Fibonacci-based strategy.
+     */
     private WaitStrategy retryWaitStrategy = WaitStrategies.fibonacciWait();
 
     /** The strategy to determine when to stop retrying to (re-)connect. By default, we never stop. */
@@ -149,7 +151,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
         if (!stopped)
             throw new IgniteException("Attempted to start an already started MQTT Streamer");
 
-        // for simplicity, if these are null initialize to empty lists
+        // For simplicity, if these are null initialize to empty lists.
         topics = topics == null ? new ArrayList<String>() : topics;
 
         qualitiesOfService = qualitiesOfService == null ? new ArrayList<Integer>() : qualitiesOfService;
@@ -157,45 +159,47 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
         try {
             Map<String, Object> logValues = new HashMap<>();
 
-            // parameter validations
+            // Parameter validations.
             A.notNull(getStreamer(), "streamer");
             A.notNull(getIgnite(), "ignite");
-            A.ensure(!(getSingleTupleExtractor() == null && getMultipleTupleExtractor() == null), "tuple extractor missing");
-            A.ensure(getSingleTupleExtractor() == null || getMultipleTupleExtractor() == null, "cannot provide " +
-                "both single and multiple tuple extractor");
+            A.ensure(!(getSingleTupleExtractor() == null && getMultipleTupleExtractor() == null),
+                "tuple extractor missing");
+            A.ensure(getSingleTupleExtractor() == null || getMultipleTupleExtractor() == null,
+                "cannot provide both single and multiple tuple extractor");
             A.notNullOrEmpty(brokerUrl, "broker URL");
 
-            // if the client ID is empty, generate one
+            // If the client ID is empty, generate one.
             if (clientId == null || clientId.length() == 0)
                 clientId = MqttClient.generateClientId();
 
-            // if we have both a single topic and a list of topics (but the list of topic is not of
-            // size 1 and == topic, as this would be a case of re-initialization), fail
+            // If we have both a single topic and a list of topics (but the list of topic is not of
+            // size 1 and == topic, as this would be a case of re-initialization), fail.
             if (topic != null && topic.length() > 0 && !topics.isEmpty() &&
                 topics.size() != 1 && !topics.get(0).equals(topic))
-                throw new IllegalArgumentException("Cannot specify both a single topic and a list at the same time");
+                throw new IllegalArgumentException("Cannot specify both a single topic and a list at the same time.");
 
-            // same as above but for QoS
+            // Same as above but for QoS.
             if (qualityOfService != null && !qualitiesOfService.isEmpty() && qualitiesOfService.size() != 1 &&
                 !qualitiesOfService.get(0).equals(qualityOfService))
-                throw new IllegalArgumentException("Cannot specify both a single QoS and a list at the same time");
+                throw new IllegalArgumentException("Cannot specify both a single QoS and a list at the same time.");
 
-            // Paho API requires disconnect timeout if providing a quiesce timeout and disconnecting forcibly
+            // Paho API requires disconnect timeout if providing a quiesce timeout and disconnecting forcibly.
             if (disconnectForcibly && disconnectQuiesceTimeout != null)
                 A.notNull(disconnectForciblyTimeout, "disconnect timeout cannot be null when disconnecting forcibly " +
                     "with quiesce");
 
-            // if we have multiple topics
+            // If we have multiple topics.
             if (!topics.isEmpty()) {
                 for (String t : topics)
                     A.notNullOrEmpty(t, "topic in list of topics");
 
-                A.ensure(qualitiesOfService.isEmpty() || qualitiesOfService.size() == topics.size(), "qualities of " +
-                    "service must be either empty or have the same size as topics list");
+                A.ensure(qualitiesOfService.isEmpty() || qualitiesOfService.size() == topics.size(),
+                    "qualities of service must be either empty or have the same size as topics list");
 
                 logValues.put("topics", topics);
             }
-            else {  // just the single topic
+            else {
+                // Just the single topic.
                 topics.add(topic);
 
                 if (qualityOfService != null)
@@ -204,29 +208,29 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
                 logValues.put("topic", topic);
             }
 
-            // finish building log values
+            // Finish building log values.
             logValues.put("brokerUrl", brokerUrl);
             logValues.put("clientId", clientId);
 
-            // cache log values
+            // Cache log values.
             cachedLogValues = "[" + Joiner.on(", ").withKeyValueSeparator("=").join(logValues) + "]";
 
-            // create logger
+            // Create logger.
             log = getIgnite().log();
 
-            // create the mqtt client
+            // Create the MQTT client.
             if (persistence == null)
                 client = new MqttClient(brokerUrl, clientId);
             else
                 client = new MqttClient(brokerUrl, clientId, persistence);
 
-            // set this as a callback
+            // Set this as a callback.
             client.setCallback(this);
 
-            // set stopped to false, as the connection will start async
+            // Set stopped to false, as the connection will start async.
             stopped = false;
 
-            // build retrier
+            // Build retrier.
             Retryer<Boolean> retrier = RetryerBuilder.<Boolean>newBuilder()
                 .retryIfResult(new Predicate<Boolean>() {
                     @Override public boolean apply(Boolean connected) {
@@ -238,29 +242,29 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
                 .withStopStrategy(retryStopStrategy)
                 .build();
 
-            // create the connection retrier
+            // Create the connection retrier.
             connectionRetrier = new MqttConnectionRetrier(retrier);
 
             log.info("Starting MQTT Streamer " + cachedLogValues);
 
-            // connect
+            // Connect.
             connectionRetrier.connect();
-
         }
-        catch (Throwable t) {
-            throw new IgniteException("Exception while initializing MqttStreamer", t);
+        catch (Exception e) {
+            throw new IgniteException("Failed to initialize MQTT Streamer.", e);
         }
-
     }
 
     /**
      * Stops streamer.
+     *
+     * @throws IgniteException If failed.
      */
     public void stop() throws IgniteException {
         if (stopped)
-            throw new IgniteException("Attempted to stop an already stopped MQTT Streamer");
+            throw new IgniteException("Failed to stop MQTT Streamer (already stopped).");
 
-        // stop the retrier
+        // Stop the retrier.
         connectionRetrier.stop();
 
         try {
@@ -273,23 +277,22 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
 
                 else
                     client.disconnectForcibly(disconnectQuiesceTimeout, disconnectForciblyTimeout);
-
-            } else {
+            }
+            else {
                 if (disconnectQuiesceTimeout == null)
                     client.disconnect();
 
                 else
                     client.disconnect(disconnectQuiesceTimeout);
-
             }
 
             client.close();
+
             connected = false;
             stopped = true;
-
         }
-        catch (Throwable t) {
-            throw new IgniteException("Exception while stopping MqttStreamer", t);
+        catch (Exception e) {
+            throw new IgniteException("Failed to stop Exception while stopping MQTT Streamer.", e);
         }
     }
 
@@ -502,9 +505,9 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     }
 
     /**
-     * Sets whether to disconnect forcibly or not when shutting down. By default, it's <tt>false</tt>.
+     * Sets whether to disconnect forcibly or not when shutting down. By default, it's {@code false}.
      *
-     * @param disconnectForcibly Whether to disconnect forcibly or not. By default, it's <tt>false</tt>.
+     * @param disconnectForcibly Whether to disconnect forcibly or not. By default, it's {@code false}.
      */
     public void setDisconnectForcibly(boolean disconnectForcibly) {
         this.disconnectForcibly = disconnectForcibly;
@@ -593,7 +596,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     }
 
     /**
-     * Sets whether to block the start() method until connected for the first time. By default, it's <tt>false</tt>.
+     * Sets whether to block the start() method until connected for the first time. By default, it's {@code false}.
      *
      * @param blockUntilConnected Whether to block or not.
      */
@@ -601,6 +604,11 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
         this.blockUntilConnected = blockUntilConnected;
     }
 
+    /**
+     * Gets whether to block the start() method until connected for the first time. By default, it's {@code false}.
+     *
+     * @return {@code true} if should connect synchronously in start.
+     */
     public boolean isBlockUntilConnected() {
         return blockUntilConnected;
     }
@@ -608,7 +616,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     /**
      * Returns whether this streamer is stopped.
      *
-     * @return <tt>true</tt> if stopped; <tt>false</tt> if not.
+     * @return {@code true} if stopped; {@code false} if not.
      */
     public boolean isStopped() {
         return stopped;
@@ -617,7 +625,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
     /**
      * Returns whether this streamer is connected.
      *
-     * @return <tt>true</tt> if connected; <tt>false</tt> if not.
+     * @return {@code true} if connected; {@code false} if not.
      */
     public boolean isConnected() {
         return connected;
@@ -628,15 +636,15 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
      * the (re-)connections.
      */
     private class MqttConnectionRetrier {
-
         /** The guava-retrying retrier object. */
         private final Retryer<Boolean> retrier;
 
         /** Single-threaded pool. */
-        private ExecutorService executor = Executors.newSingleThreadExecutor();
+        private ExecutorService exec = Executors.newSingleThreadExecutor();
 
         /**
          * Constructor.
+         *
          * @param retrier The retryier object.
          */
         public MqttConnectionRetrier(Retryer<Boolean> retrier) {
@@ -649,21 +657,21 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
         public void connect() {
             Callable<Boolean> callable = retrier.wrap(new Callable<Boolean>() {
                 @Override public Boolean call() throws Exception {
-                    // if we're already connected, return immediately
+                    // If we're already connected, return immediately.
                     if (connected)
                         return true;
 
                     if (stopped)
                         return false;
 
-                    // connect to broker
+                    // Connect to broker.
                     if (connectOptions == null)
                         client.connect();
                     else
                         client.connect(connectOptions);
 
-                    // always use the multiple topics variant of the mqtt client; even if the user specified a single
-                    // topic and/or QoS, the initialization code would have placed it inside the 1..n structures
+                    // Always use the multiple topics variant of the mqtt client; even if the user specified a single
+                    // topic and/or QoS, the initialization code would have placed it inside the 1..n structures.
                     if (qualitiesOfService.isEmpty())
                         client.subscribe(topics.toArray(new String[0]));
 
@@ -679,11 +687,12 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
                     log.info("MQTT Streamer (re-)connected and subscribed " + cachedLogValues);
 
                     connected = true;
-                    return connected;
+
+                    return true;
                 }
             });
 
-            Future<Boolean> result = executor.submit(callable);
+            Future<Boolean> result = exec.submit(callable);
 
             if (blockUntilConnected) {
                 try {
@@ -699,9 +708,7 @@ public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> impleme
          * Stops this connection utility class by shutting down the thread pool.
          */
         public void stop() {
-            executor.shutdownNow();
+            exec.shutdownNow();
         }
-
     }
-
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/056490d2/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
index 76404b8..6b07fde 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTest.java
@@ -60,11 +60,8 @@ import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT;
 
 /**
  * Test for {@link MqttStreamer}.
- *
- * @author Raul Kripalani
  */
 public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
-
     /** The test data. */
     private static final Map<Integer, String> TEST_DATA = new HashMap<>();
 
@@ -106,8 +103,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     *
-     * @throws Exception
+     * @throws Exception If failed.
      */
     @Before @SuppressWarnings("unchecked")
     public void beforeTest() throws Exception {
@@ -154,8 +150,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     *
-     * @throws Exception
+     * @throws Exception If failed.
      */
     @After
     public void afterTest() throws Exception {
@@ -175,7 +170,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testSingleTopic_NoQoS_OneEntryPerMessage() throws Exception {
         // configure streamer
@@ -197,7 +192,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testMultipleTopics_NoQoS_OneEntryPerMessage() throws Exception {
         // configure streamer
@@ -223,7 +218,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testSingleTopic_NoQoS_MultipleEntriesOneMessage() throws Exception {
         // configure streamer
@@ -245,7 +240,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testMultipleTopics_NoQoS_MultipleEntriesOneMessage() throws Exception {
         // configure streamer
@@ -271,7 +266,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testSingleTopic_NoQoS_ConnectOptions_Durable() throws Exception {
         // configure streamer
@@ -312,7 +307,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testSingleTopic_NoQoS_Reconnect() throws Exception {
         // configure streamer
@@ -358,7 +353,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testSingleTopic_NoQoS_RetryOnce() throws Exception {
         // configure streamer
@@ -397,7 +392,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testMultipleTopics_MultipleQoS_OneEntryPerMessage() throws Exception {
         // configure streamer
@@ -424,7 +419,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testMultipleTopics_MultipleQoS_Mismatch() throws Exception {
         // configure streamer
@@ -443,7 +438,8 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @param dataStreamer Streamer.
+     * @return MQTT streamer.
      */
     private MqttStreamer<Integer, String> createMqttStreamer(IgniteDataStreamer<Integer, String> dataStreamer) {
         MqttStreamer<Integer, String> streamer = new MqttStreamer<>();
@@ -460,10 +456,15 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @param topics Topics.
+     * @param fromIdx From index.
+     * @param cnt Count.
+     * @param singleMsg Single message flag.
+     * @throws MqttException If failed.
      */
-    private void sendMessages(final List<String> topics, int fromIdx, int count, boolean singleMessage) throws MqttException {
-        if (singleMessage) {
+    private void sendMessages(final List<String> topics, int fromIdx, int cnt, boolean singleMsg)
+        throws MqttException {
+        if (singleMsg) {
             final List<StringBuilder> sbs = new ArrayList<>(topics.size());
 
             // initialize String Builders for each topic
@@ -474,7 +475,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
             });
 
             // fill String Builders for each topic
-            F.forEach(F.range(fromIdx, fromIdx + count), new IgniteInClosure<Integer>() {
+            F.forEach(F.range(fromIdx, fromIdx + cnt), new IgniteInClosure<Integer>() {
                 @Override public void apply(Integer integer) {
                     sbs.get(integer % topics.size()).append(integer.toString() + "," + TEST_DATA.get(integer) + "\n");
                 }
@@ -488,7 +489,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
             }
         }
         else {
-            for (int i = fromIdx; i < fromIdx + count; i++) {
+            for (int i = fromIdx; i < fromIdx + cnt; i++) {
                 byte[] payload = (i + "," + TEST_DATA.get(i)).getBytes();
 
                 MqttMessage msg = new MqttMessage(payload);
@@ -499,14 +500,16 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @throws Exception
+     * @param expect Expected count.
+     * @return Latch to be counted down in listener.
      */
     private CountDownLatch subscribeToPutEvents(int expect) {
         Ignite ignite = grid();
 
         // Listen to cache PUT events and expect as many as messages as test data items
         final CountDownLatch latch = new CountDownLatch(expect);
-        @SuppressWarnings("serial") IgniteBiPredicate<UUID, CacheEvent> callback = new IgniteBiPredicate<UUID, CacheEvent>() {
+
+        IgniteBiPredicate<UUID, CacheEvent> callback = new IgniteBiPredicate<UUID, CacheEvent>() {
             @Override public boolean apply(UUID uuid, CacheEvent evt) {
                 latch.countDown();
 
@@ -514,32 +517,32 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
             }
         };
 
-        remoteListener = ignite.events(ignite.cluster().forCacheNodes(null)).remoteListen(callback, null, EVT_CACHE_OBJECT_PUT);
+        remoteListener = ignite.events(ignite.cluster().forCacheNodes(null))
+            .remoteListen(callback, null, EVT_CACHE_OBJECT_PUT);
+
         return latch;
     }
 
     /**
-     * @throws Exception
+     * @param cnt Count.
      */
-    private void assertCacheEntriesLoaded(int count) {
+    private void assertCacheEntriesLoaded(int cnt) {
         // get the cache and check that the entries are present
         IgniteCache<Integer, String> cache = grid().cache(null);
 
         // for each key from 0 to count from the TEST_DATA (ordered by key), check that the entry is present in cache
-        for (Integer key : new ArrayList<>(new TreeSet<>(TEST_DATA.keySet())).subList(0, count))
+        for (Integer key : new ArrayList<>(new TreeSet<>(TEST_DATA.keySet())).subList(0, cnt))
             assertEquals(TEST_DATA.get(key), cache.get(key));
 
         // assert that the cache exactly the specified amount of elements
-        assertEquals(count, cache.size(CachePeekMode.ALL));
+        assertEquals(cnt, cache.size(CachePeekMode.ALL));
 
         // remove the event listener
         grid().events(grid().cluster().forCacheNodes(null)).stopRemoteListen(remoteListener);
     }
 
     /**
-     * Returns a {@link StreamSingleTupleExtractor} for testing.
-     *
-     * @throws Exception
+     * @return {@link StreamSingleTupleExtractor} for testing.
      */
     public static StreamSingleTupleExtractor<MqttMessage, Integer, String> singleTupleExtractor() {
         return new StreamSingleTupleExtractor<MqttMessage, Integer, String>() {
@@ -552,9 +555,7 @@ public class IgniteMqttStreamerTest extends GridCommonAbstractTest {
     }
 
     /**
-     * Returns a {@link StreamMultipleTupleExtractor} for testing.
-     *
-     * @throws Exception
+     * @return {@link StreamMultipleTupleExtractor} for testing.
      */
     public static StreamMultipleTupleExtractor<MqttMessage, Integer, String> multipleTupleExtractor() {
         return new StreamMultipleTupleExtractor<MqttMessage, Integer, String>() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/056490d2/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
index 413eaab..ed0c2f7 100644
--- a/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
+++ b/modules/mqtt/src/test/java/org/apache/ignite/stream/mqtt/IgniteMqttStreamerTestSuite.java
@@ -22,8 +22,6 @@ import org.junit.runners.Suite;
 
 /**
  * MQTT streamer tests.
- *
- * @author Raul Kripalani
  */
 @RunWith(Suite.class)
 @Suite.SuiteClasses({


[26/31] ignite git commit: ignite-1607 Implemented deadlock-free optimistic serializable tx mode

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 6db00ab..af43113 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
@@ -18,7 +18,6 @@
 package org.apache.ignite.internal.processors.cache.distributed.near;
 
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -36,17 +35,14 @@ import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
 import org.apache.ignite.internal.processors.cache.GridCacheMvccFuture;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxMapping;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
-import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException;
 import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
 import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
 import org.apache.ignite.internal.util.GridConcurrentHashSet;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
-import org.apache.ignite.internal.util.lang.GridPlainRunnable;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.C1;
 import org.apache.ignite.internal.util.typedef.CI1;
@@ -57,7 +53,6 @@ import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteClosure;
 import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.transactions.TransactionOptimisticException;
 import org.apache.ignite.transactions.TransactionTimeoutException;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentLinkedDeque8;
@@ -69,7 +64,7 @@ import static org.apache.ignite.transactions.TransactionState.PREPARING;
 /**
  *
  */
-public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAdapter
+public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepareFutureAdapter
     implements GridCacheMvccFuture<IgniteInternalTx> {
     /** */
     @GridToStringInclude
@@ -82,7 +77,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
     public GridNearOptimisticTxPrepareFuture(GridCacheSharedContext cctx, GridNearTxLocal tx) {
         super(cctx, tx);
 
-        assert tx.optimistic() : tx;
+        assert tx.optimistic() && !tx.serializable() : tx;
     }
 
     /** {@inheritDoc} */
@@ -139,11 +134,9 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
     }
 
     /**
-     * @param nodeId Failed node ID.
-     * @param mappings Remaining mappings.
      * @param e Error.
      */
-    void onError(@Nullable UUID nodeId, @Nullable Iterable<GridDistributedTxMapping> mappings, Throwable e) {
+    void onError(Throwable e) {
         if (X.hasCause(e, ClusterTopologyCheckedException.class) || X.hasCause(e, ClusterTopologyException.class)) {
             if (tx.onePhaseCommit()) {
                 tx.markForBackupCheck();
@@ -157,12 +150,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
         if (err.compareAndSet(null, e)) {
             boolean marked = tx.setRollbackOnly();
 
-            if (e instanceof IgniteTxOptimisticCheckedException) {
-                assert nodeId != null : "Missing node ID for optimistic failure exception: " + e;
-
-                tx.removeKeysMapping(nodeId, mappings);
-            }
-
             if (e instanceof IgniteTxRollbackCheckedException) {
                 if (marked) {
                     try {
@@ -199,7 +186,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
     /** {@inheritDoc} */
     @Override public void onResult(UUID nodeId, GridNearTxPrepareResponse res) {
         if (!isDone()) {
-            for (IgniteInternalFuture<IgniteInternalTx> fut : pending()) {
+            for (IgniteInternalFuture<GridNearTxPrepareResponse> fut : pending()) {
                 if (isMini(fut)) {
                     MiniFuture f = (MiniFuture)fut;
 
@@ -253,212 +240,38 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
         return false;
     }
 
-    /** {@inheritDoc} */
-    @Override public void prepare() {
-        // Obtain the topology version to use.
-        AffinityTopologyVersion topVer = cctx.mvcc().lastExplicitLockTopologyVersion(Thread.currentThread().getId());
-
-        // If there is another system transaction in progress, use it's topology version to prevent deadlock.
-        if (topVer == null && tx != null && tx.system()) {
-            IgniteInternalTx tx0 = cctx.tm().anyActiveThreadTx(tx);
-
-            if (tx0 != null)
-                topVer = tx0.topologyVersionSnapshot();
-        }
-
-        if (topVer != null) {
-            tx.topologyVersion(topVer);
-
-            cctx.mvcc().addFuture(this);
-
-            prepare0(false, true);
-
-            return;
-        }
-
-        prepareOnTopology(false, null);
-    }
-
-    /**
-     * @param remap Remap flag.
-     * @param c Optional closure to run after map.
-     */
-    private void prepareOnTopology(final boolean remap, @Nullable final Runnable c) {
-        GridDhtTopologyFuture topFut = topologyReadLock();
-
-        AffinityTopologyVersion topVer = null;
-
-        try {
-            if (topFut == null) {
-                assert isDone();
-
-                return;
-            }
-
-            if (topFut.isDone()) {
-                topVer = topFut.topologyVersion();
-
-                if (remap)
-                    tx.onRemap(topVer);
-                else
-                    tx.topologyVersion(topVer);
-
-                if (!remap)
-                    cctx.mvcc().addFuture(this);
-            }
-        }
-        finally {
-            topologyReadUnlock();
-        }
-
-        if (topVer != null) {
-            StringBuilder invalidCaches = null;
-
-            for (Integer cacheId : tx.activeCacheIds()) {
-                GridCacheContext ctx = cctx.cacheContext(cacheId);
-
-                assert ctx != null : cacheId;
-
-                Throwable err = topFut.validateCache(ctx);
-
-                if (err != null) {
-                    if (invalidCaches != null)
-                        invalidCaches.append(", ");
-                    else
-                        invalidCaches = new StringBuilder();
-
-                    invalidCaches.append(U.maskName(ctx.name()));
-                }
-            }
-
-            if (invalidCaches != null) {
-                onDone(new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
-                    invalidCaches.toString()));
-
-                return;
-            }
-
-            prepare0(remap, false);
-
-            if (c != null)
-                c.run();
-        }
-        else {
-            topFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
-                @Override public void apply(final IgniteInternalFuture<AffinityTopologyVersion> fut) {
-                    cctx.kernalContext().closure().runLocalSafe(new GridPlainRunnable() {
-                        @Override public void run() {
-                            try {
-                                fut.get();
-
-                                prepareOnTopology(remap, c);
-                            }
-                            catch (IgniteCheckedException e) {
-                                onDone(e);
-                            }
-                            finally {
-                                cctx.txContextReset();
-                            }
-                        }
-                    });
-                }
-            });
-        }
-    }
-
-    /**
-     * Acquires topology read lock.
-     *
-     * @return Topology ready future.
-     */
-    private GridDhtTopologyFuture topologyReadLock() {
-        if (tx.activeCacheIds().isEmpty())
-            return cctx.exchange().lastTopologyFuture();
-
-        GridCacheContext<?, ?> nonLocCtx = null;
-
-        for (int cacheId : tx.activeCacheIds()) {
-            GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
-            if (!cacheCtx.isLocal()) {
-                nonLocCtx = cacheCtx;
-
-                break;
-            }
-        }
-
-        if (nonLocCtx == null)
-            return cctx.exchange().lastTopologyFuture();
-
-        nonLocCtx.topology().readLock();
-
-        if (nonLocCtx.topology().stopping()) {
-            onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
-                nonLocCtx.name()));
-
-            return null;
-        }
-
-        return nonLocCtx.topology().topologyVersionFuture();
-    }
-
-    /**
-     * Releases topology read lock.
-     */
-    private void topologyReadUnlock() {
-        if (!tx.activeCacheIds().isEmpty()) {
-            GridCacheContext<?, ?> nonLocCtx = null;
-
-            for (int cacheId : tx.activeCacheIds()) {
-                GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
-                if (!cacheCtx.isLocal()) {
-                    nonLocCtx = cacheCtx;
-
-                    break;
-                }
-            }
-
-            if (nonLocCtx != null)
-                nonLocCtx.topology().readUnlock();
-        }
-    }
-
     /**
      * Initializes future.
      *
      * @param remap Remap flag.
      * @param topLocked {@code True} if thread already acquired lock preventing topology change.
      */
-    private void prepare0(boolean remap, boolean topLocked) {
+    @Override protected void prepare0(boolean remap, boolean topLocked) {
         try {
             boolean txStateCheck = remap ? tx.state() == PREPARING : tx.state(PREPARING);
 
             if (!txStateCheck) {
                 if (tx.setRollbackOnly()) {
                     if (tx.timedOut())
-                        onError(null, null, new IgniteTxTimeoutCheckedException("Transaction timed out and " +
+                        onError(new IgniteTxTimeoutCheckedException("Transaction timed out and " +
                             "was rolled back: " + this));
                     else
-                        onError(null, null, new IgniteCheckedException("Invalid transaction state for prepare " +
+                        onError(new IgniteCheckedException("Invalid transaction state for prepare " +
                             "[state=" + tx.state() + ", tx=" + this + ']'));
                 }
                 else
-                    onError(null, null, new IgniteTxRollbackCheckedException("Invalid transaction state for " +
+                    onError(new IgniteTxRollbackCheckedException("Invalid transaction state for " +
                         "prepare [state=" + tx.state() + ", tx=" + this + ']'));
 
                 return;
             }
 
-            prepare(
-                tx.optimistic() && tx.serializable() ? tx.readEntries() : Collections.<IgniteTxEntry>emptyList(),
-                tx.writeEntries(),
-                topLocked);
+            prepare(tx.writeEntries(), topLocked);
 
             markInitialized();
         }
-        catch (TransactionTimeoutException | TransactionOptimisticException e) {
-            onError(cctx.localNodeId(), null, e);
+        catch (TransactionTimeoutException e) {
+            onError( e);
         }
         catch (IgniteCheckedException e) {
             onDone(e);
@@ -466,13 +279,11 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
     }
 
     /**
-     * @param reads Read entries.
      * @param writes Write entries.
      * @param topLocked {@code True} if thread already acquired lock preventing topology change.
      * @throws IgniteCheckedException If failed.
      */
     private void prepare(
-        Iterable<IgniteTxEntry> reads,
         Iterable<IgniteTxEntry> writes,
         boolean topLocked
     ) throws IgniteCheckedException {
@@ -484,7 +295,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
 
         ConcurrentLinkedDeque8<GridDistributedTxMapping> mappings = new ConcurrentLinkedDeque8<>();
 
-        if (!F.isEmpty(reads) || !F.isEmpty(writes)) {
+        if (!F.isEmpty(writes)) {
             for (int cacheId : tx.activeCacheIds()) {
                 GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
 
@@ -500,25 +311,8 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
         // Assign keys to primary nodes.
         GridDistributedTxMapping cur = null;
 
-        for (IgniteTxEntry read : reads) {
-            GridDistributedTxMapping updated = map(read, topVer, cur, false, topLocked);
-
-            if (cur != updated) {
-                mappings.offer(updated);
-
-                if (updated.node().isLocal()) {
-                    if (read.context().isNear())
-                        tx.nearLocallyMapped(true);
-                    else if (read.context().isColocated())
-                        tx.colocatedLocallyMapped(true);
-                }
-
-                cur = updated;
-            }
-        }
-
         for (IgniteTxEntry write : writes) {
-            GridDistributedTxMapping updated = map(write, topVer, cur, true, topLocked);
+            GridDistributedTxMapping updated = map(write, topVer, cur, topLocked);
 
             if (cur != updated) {
                 mappings.offer(updated);
@@ -576,7 +370,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
             futId,
             tx.topologyVersion(),
             tx,
-            tx.optimistic() && tx.serializable() ? m.reads() : null,
+            null,
             m.writes(),
             m.near(),
             txMapping.transactionNodes(),
@@ -604,7 +398,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
                 tx.userPrepare();
             }
             catch (IgniteCheckedException e) {
-                onError(null, null, e);
+                onError(e);
             }
         }
 
@@ -651,7 +445,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
      * @param entry Transaction entry.
      * @param topVer Topology version.
      * @param cur Current mapping.
-     * @param waitLock Wait lock flag.
      * @param topLocked {@code True} if thread already acquired lock preventing topology change.
      * @return Mapping.
      */
@@ -659,7 +452,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
         IgniteTxEntry entry,
         AffinityTopologyVersion topVer,
         @Nullable GridDistributedTxMapping cur,
-        boolean waitLock,
         boolean topLocked
     ) {
         GridCacheContext cacheCtx = entry.context();
@@ -687,7 +479,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
             entry.cached(cacheCtx.local().entryEx(entry.key(), topVer));
 
         if (cacheCtx.isNear() || cacheCtx.isLocal()) {
-            if (waitLock && entry.explicitVersion() == null)
+            if (entry.explicitVersion() == null)
                 lockKeys.add(entry.txKey());
         }
 
@@ -749,7 +541,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
     /**
      *
      */
-    private class MiniFuture extends GridFutureAdapter<IgniteInternalTx> {
+    private class MiniFuture extends GridFutureAdapter<GridNearTxPrepareResponse> {
         /** */
         private static final long serialVersionUID = 0L;
 
@@ -828,7 +620,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
 
                 // Fail the whole future (make sure not to remap on different primary node
                 // to prevent multiple lock coordinators).
-                onError(null, null, e);
+                onError(e);
             }
         }
 
@@ -836,14 +628,14 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
          * @param nodeId Failed node ID.
          * @param res Result callback.
          */
-        void onResult(UUID nodeId, GridNearTxPrepareResponse res) {
+        void onResult(UUID nodeId, final GridNearTxPrepareResponse res) {
             if (isDone())
                 return;
 
             if (rcvRes.compareAndSet(false, true)) {
                 if (res.error() != null) {
                     // Fail the whole compound future.
-                    onError(nodeId, mappings, res.error());
+                    onError(res.error());
                 }
                 else {
                     if (res.clientRemapVersion() != null) {
@@ -877,7 +669,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
                             proceedPrepare(mappings);
 
                         // Finish this mini future.
-                        onDone(tx);
+                        onDone((GridNearTxPrepareResponse)null);
                     }
                 }
             }
@@ -889,7 +681,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearTxPrepareFutureAd
         private void remap() {
             prepareOnTopology(true, new Runnable() {
                 @Override public void run() {
-                    onDone(tx);
+                    onDone((GridNearTxPrepareResponse)null);
                 }
             });
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
new file mode 100644
index 0000000..fd9183e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.distributed.near;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
+import org.apache.ignite.internal.util.lang.GridPlainRunnable;
+import org.apache.ignite.internal.util.typedef.CI1;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public abstract class GridNearOptimisticTxPrepareFutureAdapter extends GridNearTxPrepareFutureAdapter {
+    /**
+     * @param cctx Context.
+     * @param tx Transaction.
+     */
+    public GridNearOptimisticTxPrepareFutureAdapter(GridCacheSharedContext cctx, GridNearTxLocal tx) {
+        super(cctx, tx);
+
+        assert tx.optimistic() : tx;
+    }
+
+    /** {@inheritDoc} */
+    @Override public final void prepare() {
+        // Obtain the topology version to use.
+        AffinityTopologyVersion topVer = cctx.mvcc().lastExplicitLockTopologyVersion(Thread.currentThread().getId());
+
+        // If there is another system transaction in progress, use it's topology version to prevent deadlock.
+        if (topVer == null && tx != null && tx.system()) {
+            IgniteInternalTx tx0 = cctx.tm().anyActiveThreadTx(tx);
+
+            if (tx0 != null)
+                topVer = tx0.topologyVersionSnapshot();
+        }
+
+        if (topVer != null) {
+            tx.topologyVersion(topVer);
+
+            cctx.mvcc().addFuture(this);
+
+            prepare0(false, true);
+
+            return;
+        }
+
+        prepareOnTopology(false, null);
+    }
+
+    /**
+     * Acquires topology read lock.
+     *
+     * @return Topology ready future.
+     */
+    protected final GridDhtTopologyFuture topologyReadLock() {
+        if (tx.activeCacheIds().isEmpty())
+            return cctx.exchange().lastTopologyFuture();
+
+        GridCacheContext<?, ?> nonLocCtx = null;
+
+        for (int cacheId : tx.activeCacheIds()) {
+            GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+            if (!cacheCtx.isLocal()) {
+                nonLocCtx = cacheCtx;
+
+                break;
+            }
+        }
+
+        if (nonLocCtx == null)
+            return cctx.exchange().lastTopologyFuture();
+
+        nonLocCtx.topology().readLock();
+
+        if (nonLocCtx.topology().stopping()) {
+            onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
+                nonLocCtx.name()));
+
+            return null;
+        }
+
+        return nonLocCtx.topology().topologyVersionFuture();
+    }
+
+    /**
+     * Releases topology read lock.
+     */
+    protected final void topologyReadUnlock() {
+        if (!tx.activeCacheIds().isEmpty()) {
+            GridCacheContext<?, ?> nonLocCtx = null;
+
+            for (int cacheId : tx.activeCacheIds()) {
+                GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+                if (!cacheCtx.isLocal()) {
+                    nonLocCtx = cacheCtx;
+
+                    break;
+                }
+            }
+
+            if (nonLocCtx != null)
+                nonLocCtx.topology().readUnlock();
+        }
+    }
+
+    /**
+     * @param remap Remap flag.
+     * @param c Optional closure to run after map.
+     */
+    protected final void prepareOnTopology(final boolean remap, @Nullable final Runnable c) {
+        GridDhtTopologyFuture topFut = topologyReadLock();
+
+        AffinityTopologyVersion topVer = null;
+
+        try {
+            if (topFut == null) {
+                assert isDone();
+
+                return;
+            }
+
+            if (topFut.isDone()) {
+                topVer = topFut.topologyVersion();
+
+                if (remap)
+                    tx.onRemap(topVer);
+                else
+                    tx.topologyVersion(topVer);
+
+                if (!remap)
+                    cctx.mvcc().addFuture(this);
+            }
+        }
+        finally {
+            topologyReadUnlock();
+        }
+
+        if (topVer != null) {
+            StringBuilder invalidCaches = null;
+
+            for (Integer cacheId : tx.activeCacheIds()) {
+                GridCacheContext ctx = cctx.cacheContext(cacheId);
+
+                assert ctx != null : cacheId;
+
+                Throwable err = topFut.validateCache(ctx);
+
+                if (err != null) {
+                    if (invalidCaches != null)
+                        invalidCaches.append(", ");
+                    else
+                        invalidCaches = new StringBuilder();
+
+                    invalidCaches.append(U.maskName(ctx.name()));
+                }
+            }
+
+            if (invalidCaches != null) {
+                onDone(new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
+                    invalidCaches.toString()));
+
+                return;
+            }
+
+            prepare0(remap, false);
+
+            if (c != null)
+                c.run();
+        }
+        else {
+            topFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
+                @Override public void apply(final IgniteInternalFuture<AffinityTopologyVersion> fut) {
+                    cctx.kernalContext().closure().runLocalSafe(new GridPlainRunnable() {
+                        @Override public void run() {
+                            try {
+                                fut.get();
+
+                                prepareOnTopology(remap, c);
+                            }
+                            catch (IgniteCheckedException e) {
+                                onDone(e);
+                            }
+                            finally {
+                                cctx.txContextReset();
+                            }
+                        }
+                    });
+                }
+            });
+        }
+    }
+
+    /**
+     * @param remap Remap flag.
+     * @param topLocked {@code True} if thread already acquired lock preventing topology change.
+     */
+    protected abstract void prepare0(boolean remap, boolean topLocked);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 62f9bb3..11d31b2 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
@@ -103,7 +103,7 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
         if (!isDone()) {
             assert res.clientRemapVersion() == null : res;
 
-            for (IgniteInternalFuture<IgniteInternalTx> fut : pending()) {
+            for (IgniteInternalFuture<GridNearTxPrepareResponse> fut : pending()) {
                 MiniFuture f = (MiniFuture)fut;
 
                 if (f.futureId().equals(res.miniId())) {
@@ -292,7 +292,7 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
     /**
      *
      */
-    private class MiniFuture extends GridFutureAdapter<IgniteInternalTx> {
+    private class MiniFuture extends GridFutureAdapter<GridNearTxPrepareResponse> {
         /** */
         private static final long serialVersionUID = 0L;
 
@@ -332,7 +332,7 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
             else {
                 onPrepareResponse(m, res);
 
-                onDone(tx);
+                onDone(res);
             }
         }
 
@@ -344,7 +344,7 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
                 tx.markForBackupCheck();
 
                 // Do not fail future for one-phase transaction right away.
-                onDone(tx);
+                onDone((GridNearTxPrepareResponse)null);
             }
 
             onError(e);

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 c3bb324..0e8aa0d 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
@@ -117,7 +117,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
         @Nullable final Collection<? extends K> keys,
         boolean forcePrimary,
         boolean skipTx,
-        @Nullable final GridCacheEntryEx entry,
         @Nullable UUID subjId,
         String taskName,
         final boolean deserializePortable,
@@ -143,7 +142,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
                 @Override public IgniteInternalFuture<Map<K, V>> op(IgniteTxLocalAdapter tx) {
                     return tx.getAllAsync(ctx,
                         ctx.cacheKeysView(keys),
-                        entry,
                         deserializePortable,
                         skipVals,
                         false,
@@ -156,7 +154,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
 
         return loadAsync(null,
             ctx.cacheKeysView(keys),
-            false,
             forcePrimary,
             subjId,
             taskName,
@@ -174,6 +171,7 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
      * @param deserializePortable Deserialize portable flag.
      * @param expiryPlc Expiry policy.
      * @param skipVals Skip values flag.
+     * @param needVer If {@code true} returns values as tuples containing value and version.
      * @return Future.
      */
     IgniteInternalFuture<Map<K, V>> txLoadAsync(GridNearTxLocal tx,
@@ -181,21 +179,23 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
         boolean readThrough,
         boolean deserializePortable,
         @Nullable IgniteCacheExpiryPolicy expiryPlc,
-        boolean skipVals) {
+        boolean skipVals,
+        boolean needVer) {
         assert tx != null;
 
         GridNearGetFuture<K, V> fut = new GridNearGetFuture<>(ctx,
             keys,
             readThrough,
-            false,
-            false,
+            /*force primary*/needVer,
             tx,
             CU.subjectId(tx, ctx.shared()),
             tx.resolveTaskName(),
             deserializePortable,
             expiryPlc,
             skipVals,
-            /*can remap*/true);
+            /*can remap*/true,
+            needVer,
+            /*keepCacheObjects*/true);
 
         // init() will register future for responses if it has remote mappings.
         fut.init();

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
index 1a4f130..46c9f3e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
@@ -266,9 +266,11 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
             }
 
             if (tx.onePhaseCommit()) {
-                finishOnePhase();
+                boolean commit = this.commit && err == null;
 
-                tx.tmFinish(commit && err == null);
+                finishOnePhase(commit);
+
+                tx.tmFinish(commit);
             }
 
             Throwable th = this.err.get();
@@ -510,9 +512,9 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
     }
 
     /**
-     *
+     * @param commit Commit flag.
      */
-    private void finishOnePhase() {
+    private void finishOnePhase(boolean commit) {
         // No need to send messages as transaction was already committed on remote node.
         // Finish local mapping only as we need send commit message to backups.
         for (GridDistributedTxMapping m : mappings.values()) {
@@ -522,6 +524,8 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
                 // Add new future.
                 if (fut != null)
                     add(fut);
+
+                break;
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index ea96649..883c285 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@ -55,14 +55,15 @@ import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
 import org.apache.ignite.internal.util.future.GridEmbeddedFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.lang.GridClosureException;
+import org.apache.ignite.internal.util.lang.GridInClosure3;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.C1;
 import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteBiInClosure;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.transactions.TransactionConcurrency;
 import org.apache.ignite.transactions.TransactionIsolation;
@@ -342,32 +343,30 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
     }
 
     /** {@inheritDoc} */
-    @Override public IgniteInternalFuture<Boolean> loadMissing(
+    @Override public IgniteInternalFuture<Void> loadMissing(
         final GridCacheContext cacheCtx,
         boolean readThrough,
         boolean async,
         final Collection<KeyCacheObject> keys,
-        boolean deserializePortable,
         boolean skipVals,
-        final IgniteBiInClosure<KeyCacheObject, Object> c
+        final boolean needVer,
+        final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c
     ) {
         if (cacheCtx.isNear()) {
             return cacheCtx.nearTx().txLoadAsync(this,
                 keys,
                 readThrough,
-                deserializePortable,
+                /*deserializePortable*/false,
                 accessPolicy(cacheCtx, keys),
-                skipVals).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Boolean>() {
-                @Override public Boolean apply(IgniteInternalFuture<Map<Object, Object>> f) {
+                skipVals,
+                needVer).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
+                @Override public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
                     try {
                         Map<Object, Object> map = f.get();
 
-                        // Must loop through keys, not map entries,
-                        // as map entries may not have all the keys.
-                        for (KeyCacheObject key : keys)
-                            c.apply(key, map.get(key.value(cacheCtx.cacheObjectContext(), false)));
+                        processLoaded(map, keys, needVer, c);
 
-                        return true;
+                        return null;
                     }
                     catch (Exception e) {
                         setRollbackOnly();
@@ -381,39 +380,73 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
             return cacheCtx.colocated().loadAsync(
                 keys,
                 readThrough,
-                /*reload*/false,
-                /*force primary*/false,
+                /*force primary*/needVer,
                 topologyVersion(),
                 CU.subjectId(this, cctx),
                 resolveTaskName(),
-                deserializePortable,
+                /*deserializePortable*/false,
                 accessPolicy(cacheCtx, keys),
                 skipVals,
-                /*can remap*/true
-            ).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Boolean>() {
-                    @Override public Boolean apply(IgniteInternalFuture<Map<Object, Object>> f) {
-                        try {
-                            Map<Object, Object> map = f.get();
-
-                            // Must loop through keys, not map entries,
-                            // as map entries may not have all the keys.
-                            for (KeyCacheObject key : keys)
-                                c.apply(key, map.get(key.value(cacheCtx.cacheObjectContext(), false)));
-
-                            return true;
-                        }
-                        catch (Exception e) {
-                            setRollbackOnly();
-
-                            throw new GridClosureException(e);
-                        }
+                /*can remap*/true,
+                needVer,
+                /*keepCacheObject*/true
+            ).chain(new C1<IgniteInternalFuture<Map<Object, Object>>, Void>() {
+                @Override public Void apply(IgniteInternalFuture<Map<Object, Object>> f) {
+                    try {
+                        Map<Object, Object> map = f.get();
+
+                        processLoaded(map, keys, needVer, c);
+
+                        return null;
                     }
-                });
+                    catch (Exception e) {
+                        setRollbackOnly();
+
+                        throw new GridClosureException(e);
+                    }
+                }
+            });
         }
         else {
             assert cacheCtx.isLocal();
 
-            return super.loadMissing(cacheCtx, readThrough, async, keys, deserializePortable, skipVals, c);
+            return super.loadMissing(cacheCtx, readThrough, async, keys, skipVals, needVer, c);
+        }
+    }
+
+    /**
+     * @param map Loaded values.
+     * @param keys Keys.
+     * @param needVer If {@code true} version is required for loaded values.
+     * @param c Closure.
+     */
+    private void processLoaded(
+        Map<Object, Object> map,
+        final Collection<KeyCacheObject> keys,
+        boolean needVer,
+        GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c) {
+        for (KeyCacheObject key : keys) {
+            Object val = map.get(key);
+
+            if (val != null) {
+                Object v;
+                GridCacheVersion ver;
+
+                if (needVer) {
+                    T2<Object, GridCacheVersion> t = (T2)val;
+
+                    v = t.get1();
+                    ver = t.get2();
+                }
+                else {
+                    v = val;
+                    ver = null;
+                }
+
+                c.apply(key, v, ver);
+            }
+            else
+                c.apply(key, null, IgniteTxEntry.SER_READ_EMPTY_ENTRY_VER);
         }
     }
 
@@ -555,36 +588,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
         }
     }
 
-
-    /**
-     * Removes mapping in case of optimistic tx failure on primary node.
-     *
-     * @param failedNodeId Failed node ID.
-     * @param mapQueue Mappings queue.
-     */
-    void removeKeysMapping(UUID failedNodeId, Iterable<GridDistributedTxMapping> mapQueue) {
-        assert failedNodeId != null;
-        assert mapQueue != null;
-
-        mappings.remove(failedNodeId);
-
-        if (!F.isEmpty(mapQueue)) {
-            for (GridDistributedTxMapping m : mapQueue) {
-                UUID nodeId = m.node().id();
-
-                GridDistributedTxMapping mapping = mappings.get(nodeId);
-
-                if (mapping != null) {
-                    for (IgniteTxEntry entry : m.entries())
-                        mapping.removeEntry(entry);
-
-                    if (mapping.entries().isEmpty())
-                        mappings.remove(nodeId);
-                }
-            }
-        }
-    }
-
     /**
      * @param nodeId Node ID to mark with explicit lock.
      * @return {@code True} if mapping was found.
@@ -621,7 +624,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
         Collection<GridCacheVersion> committedVers,
         Collection<GridCacheVersion> rolledbackVers)
     {
-        Collection<IgniteTxEntry> entries = F.concat(false, mapping.reads(), mapping.writes());
+        Collection<IgniteTxEntry> entries = F.concat(false, mapping.writes(), mapping.reads());
 
         for (IgniteTxEntry txEntry : entries) {
             while (true) {
@@ -743,8 +746,13 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
 
         if (fut == null) {
             // Future must be created before any exception can be thrown.
-            fut = optimistic() ? new GridNearOptimisticTxPrepareFuture(cctx, this) :
-                new GridNearPessimisticTxPrepareFuture(cctx, this);
+            if (optimistic()) {
+                fut = serializable() ?
+                    new GridNearOptimisticSerializableTxPrepareFuture(cctx, this) :
+                    new GridNearOptimisticTxPrepareFuture(cctx, this);
+            }
+            else
+                fut = new GridNearPessimisticTxPrepareFuture(cctx, this);
 
             if (!prepFut.compareAndSet(null, fut))
                 return prepFut.get();
@@ -871,7 +879,8 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
     public IgniteInternalFuture<GridNearTxPrepareResponse> prepareAsyncLocal(
         @Nullable Collection<IgniteTxEntry> reads,
         @Nullable Collection<IgniteTxEntry> writes,
-        Map<UUID, Collection<UUID>> txNodes, boolean last,
+        Map<UUID, Collection<UUID>> txNodes,
+        boolean last,
         Collection<UUID> lastBackups
     ) {
         if (state() != PREPARING) {
@@ -899,7 +908,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
         try {
             // At this point all the entries passed in must be enlisted in transaction because this is an
             // optimistic transaction.
-            optimisticLockEntries = writes;
+            optimisticLockEntries = (serializable() && optimistic()) ? F.concat(false, writes, reads) : writes;
 
             userPrepare();
 
@@ -1192,12 +1201,8 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
         return plc;
     }
 
-    /**
-     * @param cacheCtx Cache context.
-     * @param keys Keys.
-     * @return Expiry policy.
-     */
-    private IgniteCacheExpiryPolicy accessPolicy(GridCacheContext cacheCtx, Collection<KeyCacheObject> keys) {
+    /** {@inheritDoc} */
+    @Override protected IgniteCacheExpiryPolicy accessPolicy(GridCacheContext cacheCtx, Collection<KeyCacheObject> keys) {
         if (accessMap != null) {
             for (Map.Entry<IgniteTxKey, IgniteCacheExpiryPolicy> e : accessMap.entrySet()) {
                 if (e.getKey().cacheId() == cacheCtx.cacheId() && keys.contains(e.getKey().key()))

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
index fac7a12..45477a0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
@@ -34,7 +34,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
-import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
+import org.apache.ignite.internal.util.future.GridCompoundFuture;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
@@ -48,15 +48,15 @@ import static org.apache.ignite.internal.processors.cache.GridCacheOperation.NOO
 /**
  * Common code for tx prepare in optimistic and pessimistic modes.
  */
-public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundIdentityFuture<IgniteInternalTx>
+public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundFuture<GridNearTxPrepareResponse, IgniteInternalTx>
     implements GridCacheFuture<IgniteInternalTx> {
     /** Logger reference. */
     protected static final AtomicReference<IgniteLogger> logRef = new AtomicReference<>();
 
     /** */
-    private static final IgniteReducer<IgniteInternalTx, IgniteInternalTx> REDUCER =
-        new IgniteReducer<IgniteInternalTx, IgniteInternalTx>() {
-            @Override public boolean collect(IgniteInternalTx e) {
+    private static final IgniteReducer<GridNearTxPrepareResponse, IgniteInternalTx> REDUCER =
+        new IgniteReducer<GridNearTxPrepareResponse, IgniteInternalTx>() {
+            @Override public boolean collect(GridNearTxPrepareResponse e) {
                 return true;
             }
 
@@ -94,7 +94,7 @@ public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundIdentit
      * @param tx Transaction.
      */
     public GridNearTxPrepareFutureAdapter(GridCacheSharedContext cctx, final GridNearTxLocal tx) {
-        super(cctx.kernalContext(), REDUCER);
+        super(REDUCER);
 
         assert cctx != null;
         assert tx != null;
@@ -201,6 +201,7 @@ public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundIdentit
                 }
                 catch (GridCacheEntryRemovedException ignored) {
                     // Retry.
+                    txEntry.cached(cacheCtx.cache().entryEx(txEntry.key()));
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 cacac13..85ed881 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
@@ -67,6 +67,8 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
      *
      * @param threadId Owning thread ID.
      * @param ver Lock version.
+     * @param serOrder Version for serializable transactions ordering.
+     * @param serReadVer Optional read entry version for optimistic serializable transaction.
      * @param timeout Timeout to acquire lock.
      * @param reenter Reentry flag.
      * @param tx Transaction flag.
@@ -77,6 +79,8 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
     @Nullable public GridCacheMvccCandidate addLocal(
         long threadId,
         GridCacheVersion ver,
+        @Nullable GridCacheVersion serOrder,
+        @Nullable GridCacheVersion serReadVer,
         long timeout,
         boolean reenter,
         boolean tx,
@@ -91,6 +95,11 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
         synchronized (this) {
             checkObsolete();
 
+            if (serReadVer != null) {
+                if (!checkSerializableReadVersion(serReadVer))
+                    return null;
+            }
+
             GridCacheMvcc mvcc = mvccExtras();
 
             if (mvcc == null) {
@@ -103,12 +112,16 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
 
             cand = mvcc.addLocal(
                 this,
+                /*nearNodeId*/null,
+                /*nearVer*/null,
                 threadId,
                 ver,
                 timeout,
+                serOrder,
                 reenter,
                 tx,
-                implicitSingle
+                implicitSingle,
+                /*dht-local*/false
             );
 
             owner = mvcc.localOwner();
@@ -191,10 +204,16 @@ public class GridLocalCacheEntry extends GridCacheMapEntry {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean tmLock(IgniteInternalTx tx, long timeout) throws GridCacheEntryRemovedException {
+    @Override public boolean tmLock(IgniteInternalTx tx,
+        long timeout,
+        @Nullable GridCacheVersion serOrder,
+        GridCacheVersion serReadVer)
+        throws GridCacheEntryRemovedException {
         GridCacheMvccCandidate cand = addLocal(
             tx.threadId(),
             tx.xidVersion(),
+            serOrder,
+            serReadVer,
             timeout,
             /*reenter*/false,
             /*tx*/true,

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 7018c4e..cb14b4c 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
@@ -225,6 +225,8 @@ public final class GridLocalLockFuture<K, V> extends GridFutureAdapter<Boolean>
         GridCacheMvccCandidate c = entry.addLocal(
             threadId,
             lockVer,
+            null,
+            null,
             timeout,
             !inTx(),
             inTx(),

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
index 0bf6ea2..8446665 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
@@ -495,7 +495,6 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> {
         @Nullable final Collection<? extends K> keys,
         final boolean forcePrimary,
         boolean skipTx,
-        @Nullable final GridCacheEntryEx entry,
         @Nullable UUID subjId,
         final String taskName,
         final boolean deserializePortable,
@@ -595,10 +594,6 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> {
                 catch (GridCacheEntryRemovedException ignored) {
                     // No-op, retry.
                 }
-                catch (GridCacheFilterFailedException ignored) {
-                    // No-op, skip the key.
-                    break;
-                }
                 finally {
                     if (entry != null)
                         ctx.evicts().touch(entry, ctx.affinity().affinityTopologyVersion());
@@ -615,7 +610,6 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> {
         return getAllAsync(
             keys,
             opCtx == null || !opCtx.skipStore(),
-            null,
             false,
             subjId,
             taskName,
@@ -1284,9 +1278,6 @@ public class GridLocalAtomicCache<K, V> extends GridCacheAdapter<K, V> {
                 catch (GridCacheEntryRemovedException ignore) {
                     assert false : "Entry cannot become obsolete while holding lock.";
                 }
-                catch (GridCacheFilterFailedException ignore) {
-                    assert false : "Filter should never fail with failFast=false and empty filter.";
-                }
             }
 
             // Store final batch.

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
index c0c2284..716676f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTransactionsImpl.java
@@ -147,12 +147,6 @@ public class IgniteTransactionsImpl<K, V> implements IgniteTransactionsEx {
         cctx.kernalContext().gateway().readLock();
 
         try {
-            TransactionConfiguration cfg = cctx.gridConfig().getTransactionConfiguration();
-
-            if (!cfg.isTxSerializableEnabled() && isolation == SERIALIZABLE)
-                throw new IllegalArgumentException("SERIALIZABLE isolation level is disabled (to enable change " +
-                    "'txSerializableEnabled' configuration property)");
-
             IgniteInternalTx tx = cctx.tm().userTx(sysCacheCtx);
 
             if (tx != null)

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index 7d7e3e8..1c82636 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -325,7 +325,8 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
 
         threadId = Thread.currentThread().getId();
 
-        log = U.logger(cctx.kernalContext(), logRef, this);
+        if (log == null)
+            log = U.logger(cctx.kernalContext(), logRef, this);
     }
 
     /**
@@ -374,7 +375,8 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
         implicitSingle = false;
         loc = false;
 
-        log = U.logger(cctx.kernalContext(), logRef, this);
+        if (log == null)
+            log = U.logger(cctx.kernalContext(), logRef, this);
     }
 
     /** {@inheritDoc} */
@@ -430,6 +432,9 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
 
     /** {@inheritDoc} */
     @Override public Collection<IgniteTxEntry> optimisticLockEntries() {
+        if (serializable() && optimistic())
+            return F.concat(false, writeEntries(), readEntries());
+
         return writeEntries();
     }
 
@@ -1267,88 +1272,81 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
         if (F.isEmpty(txEntry.entryProcessors()))
             return F.t(txEntry.op(), txEntry.value());
         else {
-            try {
-                boolean recordEvt = cctx.gridEvents().isRecordable(EVT_CACHE_OBJECT_READ);
+            boolean recordEvt = cctx.gridEvents().isRecordable(EVT_CACHE_OBJECT_READ);
 
-                CacheObject cacheVal = txEntry.hasValue() ? txEntry.value() :
-                    txEntry.cached().innerGet(this,
-                        /*swap*/false,
-                        /*read through*/false,
-                        /*fail fast*/true,
-                        /*unmarshal*/true,
-                        /*metrics*/metrics,
-                        /*event*/recordEvt,
-                        /*temporary*/true,
-                        /*subjId*/subjId,
-                        /**closure name */recordEvt ? F.first(txEntry.entryProcessors()).get1() : null,
-                        resolveTaskName(),
-                        null);
+            CacheObject cacheVal = txEntry.hasValue() ? txEntry.value() :
+                txEntry.cached().innerGet(this,
+                    /*swap*/false,
+                    /*read through*/false,
+                    /*fail fast*/true,
+                    /*unmarshal*/true,
+                    /*metrics*/metrics,
+                    /*event*/recordEvt,
+                    /*temporary*/true,
+                    /*subjId*/subjId,
+                    /**closure name */recordEvt ? F.first(txEntry.entryProcessors()).get1() : null,
+                    resolveTaskName(),
+                    null);
 
-                boolean modified = false;
+            boolean modified = false;
 
-                Object val = null;
+            Object val = null;
 
-                Object key = null;
+            Object key = null;
 
-                GridCacheVersion ver;
-
-                try {
-                    ver = txEntry.cached().version();
-                }
-                catch (GridCacheEntryRemovedException e) {
-                    assert optimistic() : txEntry;
+            GridCacheVersion ver;
 
-                    if (log.isDebugEnabled())
-                        log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
+            try {
+                ver = txEntry.cached().version();
+            }
+            catch (GridCacheEntryRemovedException e) {
+                assert optimistic() : txEntry;
 
-                    ver = null;
-                }
+                if (log.isDebugEnabled())
+                    log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
 
-                for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : txEntry.entryProcessors()) {
-                    CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry(txEntry.context(),
-                        txEntry.key(), key, cacheVal, val, ver);
+                ver = null;
+            }
 
-                    try {
-                        EntryProcessor<Object, Object, Object> processor = t.get1();
+            for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : txEntry.entryProcessors()) {
+                CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry(txEntry.context(),
+                    txEntry.key(), key, cacheVal, val, ver);
 
-                        processor.process(invokeEntry, t.get2());
+                try {
+                    EntryProcessor<Object, Object, Object> processor = t.get1();
 
-                        val = invokeEntry.getValue();
+                    processor.process(invokeEntry, t.get2());
 
-                        key = invokeEntry.key();
-                    }
-                    catch (Exception ignore) {
-                        // No-op.
-                    }
+                    val = invokeEntry.getValue();
 
-                    modified |= invokeEntry.modified();
+                    key = invokeEntry.key();
+                }
+                catch (Exception ignore) {
+                    // No-op.
                 }
 
-                if (modified)
-                    cacheVal = cacheCtx.toCacheObject(cacheCtx.unwrapTemporary(val));
+                modified |= invokeEntry.modified();
+            }
 
-                GridCacheOperation op = modified ? (val == null ? DELETE : UPDATE) : NOOP;
+            if (modified)
+                cacheVal = cacheCtx.toCacheObject(cacheCtx.unwrapTemporary(val));
 
-                if (op == NOOP) {
-                    ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
+            GridCacheOperation op = modified ? (val == null ? DELETE : UPDATE) : NOOP;
 
-                    if (expiry != null) {
-                        long ttl = CU.toTtl(expiry.getExpiryForAccess());
+            if (op == NOOP) {
+                ExpiryPolicy expiry = cacheCtx.expiryForTxEntry(txEntry);
 
-                        txEntry.ttl(ttl);
+                if (expiry != null) {
+                    long ttl = CU.toTtl(expiry.getExpiryForAccess());
 
-                        if (ttl == CU.TTL_ZERO)
-                            op = DELETE;
-                    }
-                }
+                    txEntry.ttl(ttl);
 
-                return F.t(op, cacheVal);
+                    if (ttl == CU.TTL_ZERO)
+                        op = DELETE;
+                }
             }
-            catch (GridCacheFilterFailedException e) {
-                assert false : "Empty filter failed for innerGet: " + e;
 
-                return null;
-            }
+            return F.t(op, cacheVal);
         }
     }
 
@@ -1498,9 +1496,8 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
      * @param e Entry to evict if it qualifies for eviction.
      * @param primaryOnly Flag to try to evict only on primary node.
      * @return {@code True} if attempt was made to evict the entry.
-     * @throws IgniteCheckedException If failed.
      */
-    protected boolean evictNearEntry(IgniteTxEntry e, boolean primaryOnly) throws IgniteCheckedException {
+    protected boolean evictNearEntry(IgniteTxEntry e, boolean primaryOnly) {
         assert e != null;
 
         if (isNearLocallyMapped(e, primaryOnly)) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 2462dda..9eb2808 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
@@ -66,6 +66,12 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
     /** */
     private static final long serialVersionUID = 0L;
 
+    /** Dummy version for non-existing entry read in SERIALIZABLE transaction. */
+    public static final GridCacheVersion SER_READ_EMPTY_ENTRY_VER = new GridCacheVersion(0, 0, 0, 0);
+
+    /** Dummy version for any existing entry read in SERIALIZABLE transaction. */
+    public static final GridCacheVersion SER_READ_NOT_EMPTY_VER = new GridCacheVersion(0, 0, 0, 1);
+
     /** Owning transaction. */
     @GridToStringExclude
     @GridDirectTransient
@@ -175,6 +181,9 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
      */
     private byte flags;
 
+    /** */
+    private GridCacheVersion serReadVer;
+
     /**
      * Required by {@link Externalizable}
      */
@@ -316,6 +325,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
         cp.conflictVer = conflictVer;
         cp.expiryPlc = expiryPlc;
         cp.flags = flags;
+        cp.serReadVer = serReadVer;
 
         return cp;
     }
@@ -822,6 +832,23 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
         this.entryProcessorCalcVal = entryProcessorCalcVal;
     }
 
+    /**
+     * @return Read version for serializable transaction.
+     */
+    @Nullable public GridCacheVersion serializableReadVersion() {
+        return serReadVer;
+    }
+
+    /**
+     * @param serReadVer Read version for serializable transaction.
+     */
+    public void serializableReadVersion(GridCacheVersion serReadVer) {
+        assert this.serReadVer == null;
+        assert serReadVer != null;
+
+        this.serReadVer = serReadVer;
+    }
+
     /** {@inheritDoc} */
     @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
         writer.setBuffer(buf);
@@ -884,18 +911,24 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
                 writer.incrementState();
 
             case 8:
-                if (!writer.writeByteArray("transformClosBytes", transformClosBytes))
+                if (!writer.writeMessage("serReadVer", serReadVer))
                     return false;
 
                 writer.incrementState();
 
             case 9:
-                if (!writer.writeLong("ttl", ttl))
+                if (!writer.writeByteArray("transformClosBytes", transformClosBytes))
                     return false;
 
                 writer.incrementState();
 
             case 10:
+                if (!writer.writeLong("ttl", ttl))
+                    return false;
+
+                writer.incrementState();
+
+            case 11:
                 if (!writer.writeMessage("val", val))
                     return false;
 
@@ -979,7 +1012,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
                 reader.incrementState();
 
             case 8:
-                transformClosBytes = reader.readByteArray("transformClosBytes");
+                serReadVer = reader.readMessage("serReadVer");
 
                 if (!reader.isLastRead())
                     return false;
@@ -987,7 +1020,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
                 reader.incrementState();
 
             case 9:
-                ttl = reader.readLong("ttl");
+                transformClosBytes = reader.readByteArray("transformClosBytes");
 
                 if (!reader.isLastRead())
                     return false;
@@ -995,6 +1028,14 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
                 reader.incrementState();
 
             case 10:
+                ttl = reader.readLong("ttl");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 11:
                 val = reader.readMessage("val");
 
                 if (!reader.isLastRead())
@@ -1014,7 +1055,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
 
     /** {@inheritDoc} */
     @Override public byte fieldsCount() {
-        return 11;
+        return 12;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
index 530fbdf..d9786a8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
@@ -68,6 +68,7 @@ import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteFutureCancelledException;
+import org.apache.ignite.transactions.TransactionState;
 import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.internal.managers.communication.GridIoPolicy.SYSTEM_POOL;
@@ -417,7 +418,8 @@ public class IgniteTxHandler {
 
             if (tx.isRollbackOnly()) {
                 try {
-                    tx.rollback();
+                    if (tx.state() != TransactionState.ROLLED_BACK && tx.state() != TransactionState.ROLLING_BACK)
+                        tx.rollback();
                 }
                 catch (IgniteCheckedException e) {
                     U.error(log, "Failed to rollback transaction: " + tx, e);


[05/31] ignite git commit: Muted test

Posted by ra...@apache.org.
Muted test


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

Branch: refs/heads/ignite-1790
Commit: b09939f95f358a5c25c6eec5135499f50b857bb9
Parents: ea63c2d
Author: ashutak <as...@gridgain.com>
Authored: Mon Oct 26 19:03:57 2015 +0300
Committer: ashutak <as...@gridgain.com>
Committed: Mon Oct 26 19:03:57 2015 +0300

----------------------------------------------------------------------
 .../partitioned/IgnitePartitionedCountDownLatchSelfTest.java  | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b09939f9/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/partitioned/IgnitePartitionedCountDownLatchSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/partitioned/IgnitePartitionedCountDownLatchSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/partitioned/IgnitePartitionedCountDownLatchSelfTest.java
index c9c9205..fc9356e 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/partitioned/IgnitePartitionedCountDownLatchSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/partitioned/IgnitePartitionedCountDownLatchSelfTest.java
@@ -30,4 +30,9 @@ public class IgnitePartitionedCountDownLatchSelfTest extends IgniteCountDownLatc
     @Override protected CacheMode atomicsCacheMode() {
         return PARTITIONED;
     }
-}
\ No newline at end of file
+
+    /** {@inheritDoc} */
+    @Override public void testLatch() throws Exception {
+        fail("https://issues.apache.org/jira/browse/IGNITE-1793");
+    }
+}


[29/31] ignite git commit: ignite-1607 Implemented deadlock-free optimistic serializable tx mode

Posted by ra...@apache.org.
ignite-1607 Implemented deadlock-free optimistic serializable tx mode


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

Branch: refs/heads/ignite-1790
Commit: 9d7543a8dedb85f1dc904b52be3673f4a151f8e7
Parents: db88860
Author: sboikov <sb...@gridgain.com>
Authored: Wed Oct 28 10:53:29 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Oct 28 10:53:30 2015 +0300

----------------------------------------------------------------------
 .../configuration/TransactionConfiguration.java |    6 +-
 .../processors/cache/CacheMetricsImpl.java      |   12 +-
 .../processors/cache/GridCacheAdapter.java      |  459 +-
 .../processors/cache/GridCacheEntryEx.java      |   62 +-
 .../processors/cache/GridCacheMapEntry.java     |  137 +-
 .../processors/cache/GridCacheMvcc.java         |  143 +-
 .../cache/GridCacheMvccCandidate.java           |   26 +-
 .../processors/cache/GridCacheProcessor.java    |   13 -
 .../distributed/GridDistributedCacheEntry.java  |   12 +-
 .../GridDistributedTxRemoteAdapter.java         |   56 +-
 .../dht/CacheDistributedGetFutureAdapter.java   |  158 +
 .../distributed/dht/GridDhtCacheAdapter.java    |   17 +-
 .../distributed/dht/GridDhtCacheEntry.java      |   23 +-
 .../cache/distributed/dht/GridDhtGetFuture.java |  199 +-
 .../distributed/dht/GridDhtLockFuture.java      |    5 +-
 .../dht/GridDhtTransactionalCacheAdapter.java   |  105 +-
 .../cache/distributed/dht/GridDhtTxLocal.java   |    4 +-
 .../distributed/dht/GridDhtTxPrepareFuture.java |  109 +-
 .../dht/GridPartitionedGetFuture.java           |  179 +-
 .../dht/atomic/GridDhtAtomicCache.java          |   16 +-
 .../dht/colocated/GridDhtColocatedCache.java    |  130 +-
 .../colocated/GridDhtColocatedLockFuture.java   |    6 +-
 .../distributed/near/GridNearAtomicCache.java   |    2 -
 .../distributed/near/GridNearCacheAdapter.java  |   32 +-
 .../distributed/near/GridNearCacheEntry.java    |   81 +-
 .../distributed/near/GridNearGetFuture.java     |  340 +-
 .../distributed/near/GridNearGetRequest.java    |    3 -
 ...arOptimisticSerializableTxPrepareFuture.java |  930 ++++
 .../near/GridNearOptimisticTxPrepareFuture.java |  252 +-
 ...ridNearOptimisticTxPrepareFutureAdapter.java |  222 +
 .../GridNearPessimisticTxPrepareFuture.java     |    8 +-
 .../near/GridNearTransactionalCache.java        |   14 +-
 .../near/GridNearTxFinishFuture.java            |   12 +-
 .../cache/distributed/near/GridNearTxLocal.java |  157 +-
 .../near/GridNearTxPrepareFutureAdapter.java    |   13 +-
 .../cache/local/GridLocalCacheEntry.java        |   23 +-
 .../cache/local/GridLocalLockFuture.java        |    2 +
 .../local/atomic/GridLocalAtomicCache.java      |    9 -
 .../transactions/IgniteTransactionsImpl.java    |    6 -
 .../cache/transactions/IgniteTxAdapter.java     |  123 +-
 .../cache/transactions/IgniteTxEntry.java       |   51 +-
 .../cache/transactions/IgniteTxHandler.java     |    4 +-
 .../transactions/IgniteTxLocalAdapter.java      |  832 ++--
 .../cache/transactions/IgniteTxLocalEx.java     |   27 +-
 .../cache/transactions/IgniteTxManager.java     |  327 +-
 .../cache/version/GridCacheVersionManager.java  |   73 +-
 .../datastreamer/DataStreamerImpl.java          |    2 +-
 .../apache/ignite/transactions/Transaction.java |    2 +-
 .../transactions/TransactionIsolation.java      |    3 +-
 .../cache/CacheNearReaderUpdateTest.java        |  388 ++
 .../CacheSerializableTransactionsTest.java      | 4295 ++++++++++++++++++
 .../cache/CrossCacheTxRandomOperationsTest.java |    6 +
 .../GridCacheAbstractFailoverSelfTest.java      |   14 +-
 .../cache/GridCacheAbstractFullApiSelfTest.java |    4 +-
 .../GridCacheAbstractRemoveFailureTest.java     |   94 +-
 .../GridCacheConcurrentTxMultiNodeTest.java     |    3 -
 .../cache/GridCacheMvccFlagsTest.java           |    6 +-
 .../cache/GridCacheMvccPartitionedSelfTest.java |  164 +
 .../processors/cache/GridCacheMvccSelfTest.java |    3 +-
 .../processors/cache/GridCacheTestEntryEx.java  |   53 +-
 .../processors/cache/IgniteTxAbstractTest.java  |   42 +-
 .../IgniteTxMultiThreadedAbstractTest.java      |  106 +-
 ...onedNearDisabledTxMultiThreadedSelfTest.java |   31 +
 ...niteCacheClientNodeChangingTopologyTest.java |  170 +-
 .../IgniteCacheCrossCacheTxFailoverTest.java    |   19 +
 .../dht/IgniteCacheLockFailoverSelfTest.java    |   11 +
 ...eAtomicInvalidPartitionHandlingSelfTest.java |    6 +-
 .../near/GridCacheNearTxExceptionSelfTest.java  |    1 +
 ...CachePartitionedTxMultiThreadedSelfTest.java |   15 +-
 .../DataStreamerUpdateAfterLoadTest.java        |  184 +
 .../loadtests/hashmap/GridHashMapLoadTest.java  |    6 +-
 .../inmemory/GridTestSwapSpaceSpi.java          |    8 +
 .../junits/common/GridCommonAbstractTest.java   |   19 +-
 .../ignite/testsuites/IgniteCacheTestSuite.java |    4 +-
 .../testsuites/IgniteCacheTestSuite2.java       |    2 +
 .../testsuites/IgniteCacheTestSuite5.java       |   40 +
 .../config/benchmark-multicast.properties       |    5 +-
 .../IgniteAccountSerializableTxBenchmark.java   |   81 +
 .../cache/IgniteAccountTxAbstractBenchmark.java |   61 +
 .../cache/IgniteAccountTxBenchmark.java         |   74 +
 .../cache/IgniteCacheAbstractBenchmark.java     |    7 +-
 .../IgnitePutAllSerializableTxBenchmark.java    |   77 +
 .../ignite/yardstick/cache/model/Account.java   |   42 +
 83 files changed, 9229 insertions(+), 2239 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java
index 7d3cebb..fc2a6cb 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/TransactionConfiguration.java
@@ -92,15 +92,17 @@ public class TransactionConfiguration implements Serializable {
      *
      * @return {@code True} if serializable transactions are enabled, {@code false} otherwise.
      */
+    @Deprecated
     public boolean isTxSerializableEnabled() {
         return txSerEnabled;
     }
 
     /**
-     * Enables/disables serializable cache transactions. See {@link #isTxSerializableEnabled()} for more information.
-     *
      * @param txSerEnabled Flag to enable/disable serializable cache transactions.
+
+     * @deprecated This method has no effect, {@link TransactionIsolation#SERIALIZABLE} isolation is always enabled.
      */
+    @Deprecated
     public void setTxSerializableEnabled(boolean txSerEnabled) {
         this.txSerEnabled = txSerEnabled;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
index dfa0217..a60c22b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
@@ -351,7 +351,7 @@ public class CacheMetricsImpl implements CacheMetrics {
 
     /** {@inheritDoc} */
     @Override public int getTxCommitQueueSize() {
-        return cctx.tm().commitQueueSize();
+        return 0;
     }
 
     /** {@inheritDoc} */
@@ -366,12 +366,12 @@ public class CacheMetricsImpl implements CacheMetrics {
 
     /** {@inheritDoc} */
     @Override public int getTxPrepareQueueSize() {
-        return cctx.tm().prepareQueueSize();
+        return 0;
     }
 
     /** {@inheritDoc} */
     @Override public int getTxStartVersionCountsSize() {
-        return cctx.tm().startVersionCountsSize();
+        return 0;
     }
 
     /** {@inheritDoc} */
@@ -396,17 +396,17 @@ public class CacheMetricsImpl implements CacheMetrics {
 
     /** {@inheritDoc} */
     @Override public int getTxDhtCommitQueueSize() {
-        return cctx.isNear() && dhtCtx != null ? dhtCtx.tm().commitQueueSize() : -1;
+        return 0;
     }
 
     /** {@inheritDoc} */
     @Override public int getTxDhtPrepareQueueSize() {
-        return cctx.isNear() && dhtCtx != null ? dhtCtx.tm().prepareQueueSize() : -1;
+        return 0;
     }
 
     /** {@inheritDoc} */
     @Override public int getTxDhtStartVersionCountsSize() {
-        return cctx.isNear() && dhtCtx != null ? dhtCtx.tm().startVersionCountsSize() : -1;
+        return 0;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index 417b396..74951b5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@ -608,7 +608,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             Collections.singletonList(key),
             /*force primary*/false,
             /*skip tx*/false,
-            /*entry*/null,
             /*subj id*/null,
             /*task name*/null,
             /*deserialize portable*/false,
@@ -643,7 +642,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             keys,
             /*force primary*/false,
             /*skip tx*/false,
-            /*entry*/null,
             /*subj id*/null,
             /*task name*/null,
             /*deserialize portable*/false,
@@ -1273,7 +1271,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             F.asList(key),
             /*force primary*/true,
             /*skip tx*/false,
-            /*cached entry*/null,
             /*subject id*/null,
             taskName,
             /*deserialize cache objects*/true,
@@ -1291,7 +1288,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             /*force primary*/true,
             /*skip tx*/false,
             null,
-            null,
             taskName,
             true,
             false,
@@ -1317,7 +1313,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             F.asList(key),
             /*force primary*/false,
             /*skip tx*/false,
-            /*cached entry*/null,
             /*subject id*/null,
             taskName,
             /*deserialize cache objects*/true,
@@ -1339,7 +1334,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             !ctx.config().isReadFromBackup(),
             /*skip tx*/true,
             null,
-            null,
             taskName,
             !ctx.keepPortable(),
             /*skip values*/false,
@@ -1347,184 +1341,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
     }
 
     /**
-     * @param keys Keys.
-     * @param reload Reload flag.
-     * @param tx Transaction.
-     * @param subjId Subject ID.
-     * @param taskName Task name.
-     * @param vis Visitor.
-     * @return Future.
-     */
-    public IgniteInternalFuture<Object> readThroughAllAsync(final Collection<KeyCacheObject> keys,
-        boolean reload,
-        boolean skipVals,
-        @Nullable final IgniteInternalTx tx,
-        @Nullable UUID subjId,
-        String taskName,
-        final IgniteBiInClosure<KeyCacheObject, Object> vis) {
-        return ctx.closures().callLocalSafe(new GPC<Object>() {
-            @Nullable @Override public Object call() {
-                try {
-                    ctx.store().loadAll(tx, keys, vis);
-                }
-                catch (IgniteCheckedException e) {
-                    throw new GridClosureException(e);
-                }
-
-                return null;
-            }
-        }, true);
-    }
-
-    /**
-     * @param keys Keys.
-     * @param ret Return flag.
-     * @param skipVals Skip values flag.
-     * @param subjId Subject ID.
-     * @param taskName Task name.
-     * @return Future.
-     */
-    public IgniteInternalFuture<Map<KeyCacheObject, CacheObject>> reloadAllAsync0(
-        Collection<KeyCacheObject> keys,
-        boolean ret,
-        boolean skipVals,
-        @Nullable UUID subjId,
-        String taskName)
-    {
-        final AffinityTopologyVersion topVer = ctx.affinity().affinityTopologyVersion();
-
-        if (!F.isEmpty(keys)) {
-            final Map<KeyCacheObject, GridCacheVersion> keyVers = new HashMap();
-
-            for (KeyCacheObject key : keys) {
-                if (key == null)
-                    continue;
-
-                // Skip primary or backup entries for near cache.
-                if (ctx.isNear() && ctx.affinity().localNode(key, topVer))
-                    continue;
-
-                while (true) {
-                    try {
-                        GridCacheEntryEx entry = entryExSafe(key, topVer);
-
-                        if (entry == null)
-                            break;
-
-                        GridCacheVersion ver = entry.version();
-
-                        keyVers.put(key, ver);
-
-                        break;
-                    }
-                    catch (GridCacheEntryRemovedException ignore) {
-                        if (log.isDebugEnabled())
-                            log.debug("Got removed entry for reload (will retry): " + key);
-                    }
-                    catch (GridDhtInvalidPartitionException ignore) {
-                        if (log.isDebugEnabled())
-                            log.debug("Got invalid partition for key (will skip): " + key);
-
-                        break;
-                    }
-                }
-            }
-
-            final Map<KeyCacheObject, CacheObject> map =
-                ret ? U.<KeyCacheObject, CacheObject>newHashMap(keys.size()) : null;
-
-            final Collection<KeyCacheObject> absentKeys = F.view(keyVers.keySet());
-
-            final Collection<KeyCacheObject> loadedKeys = new GridConcurrentHashSet<>();
-
-            IgniteInternalFuture<Object> readFut = readThroughAllAsync(absentKeys, true, skipVals, null,
-                subjId, taskName, new CI2<KeyCacheObject, Object>() {
-                    /** Version for all loaded entries. */
-                    private GridCacheVersion nextVer = ctx.versions().next();
-
-                    /** {@inheritDoc} */
-                    @Override public void apply(KeyCacheObject key, Object val) {
-                        loadedKeys.add(key);
-
-                        GridCacheEntryEx entry = peekEx(key);
-
-                        if (entry != null) {
-                            try {
-                                GridCacheVersion curVer = keyVers.get(key);
-
-                                if (curVer != null) {
-                                    boolean wasNew = entry.isNewLocked();
-
-                                    entry.unswap();
-
-                                    CacheObject cacheVal = ctx.toCacheObject(val);
-
-                                    boolean set = entry.versionedValue(cacheVal, curVer, nextVer);
-
-                                    ctx.evicts().touch(entry, topVer);
-
-                                    if (map != null) {
-                                        if (set || wasNew)
-                                            map.put(key, cacheVal);
-                                        else {
-                                            CacheObject v = entry.peek(true, false, false, null);
-
-                                            if (v != null)
-                                                map.put(key, v);
-                                        }
-                                    }
-
-                                    if (log.isDebugEnabled()) {
-                                        log.debug("Set value loaded from store into entry [set=" + set + ", " +
-                                            "curVer=" +
-                                            curVer + ", newVer=" + nextVer + ", entry=" + entry + ']');
-                                    }
-                                }
-                                else {
-                                    if (log.isDebugEnabled()) {
-                                        log.debug("Current version was not found (either entry was removed or " +
-                                            "validation was not passed: " + entry);
-                                    }
-                                }
-                            }
-                            catch (GridCacheEntryRemovedException ignore) {
-                                if (log.isDebugEnabled()) {
-                                    log.debug("Got removed entry for reload (will not store reloaded entry) " +
-                                        "[entry=" + entry + ']');
-                                }
-                            }
-                            catch (IgniteCheckedException e) {
-                                throw new IgniteException(e);
-                            }
-                        }
-                    }
-                });
-
-            return readFut.chain(new CX1<IgniteInternalFuture<Object>, Map<KeyCacheObject, CacheObject>>() {
-                @Override public Map<KeyCacheObject, CacheObject> applyx(IgniteInternalFuture<Object> e)
-                    throws IgniteCheckedException  {
-                    // Touch all not loaded keys.
-                    for (KeyCacheObject key : absentKeys) {
-                        if (!loadedKeys.contains(key)) {
-                            GridCacheEntryEx entry = peekEx(key);
-
-                            if (entry != null)
-                                ctx.evicts().touch(entry, topVer);
-                        }
-                    }
-
-                    // Make sure there were no exceptions.
-                    e.get();
-
-                    return map;
-                }
-            });
-        }
-
-        return new GridFinishedFuture<>(Collections.<KeyCacheObject, CacheObject>emptyMap());
-    }
-
-    /**
      * @param key Key.
      * @param topVer Topology version.
      * @return Entry.
@@ -1662,11 +1478,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
      * @param keys Keys.
      * @param forcePrimary Force primary.
      * @param skipTx Skip tx.
-     * @param entry Entry.
      * @param subjId Subj Id.
      * @param taskName Task name.
      * @param deserializePortable Deserialize portable.
      * @param skipVals Skip values.
+     * @param canRemap Can remap flag.
      * @return Future for the get operation.
      * @see GridCacheAdapter#getAllAsync(Collection)
      */
@@ -1674,7 +1490,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
         @Nullable Collection<? extends K> keys,
         boolean forcePrimary,
         boolean skipTx,
-        @Nullable GridCacheEntryEx entry,
         @Nullable UUID subjId,
         String taskName,
         boolean deserializePortable,
@@ -1687,7 +1502,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         return getAllAsync(keys,
             opCtx == null || !opCtx.skipStore(),
-            entry,
             !skipTx,
             subjId,
             taskName,
@@ -1701,7 +1515,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
     /**
      * @param keys Keys.
      * @param readThrough Read through.
-     * @param cached Cached.
      * @param checkTx Check tx.
      * @param subjId Subj Id.
      * @param taskName Task name.
@@ -1709,12 +1522,12 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
      * @param forcePrimary Froce primary.
      * @param expiry Expiry policy.
      * @param skipVals Skip values.
+     * @param canRemap Can remap flag.
      * @return Future for the get operation.
      * @see GridCacheAdapter#getAllAsync(Collection)
      */
     public IgniteInternalFuture<Map<K, V>> getAllAsync(@Nullable final Collection<? extends K> keys,
         boolean readThrough,
-        @Nullable GridCacheEntryEx cached,
         boolean checkTx,
         @Nullable final UUID subjId,
         final String taskName,
@@ -1738,7 +1551,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             expiry,
             skipVals,
             false,
-            canRemap);
+            canRemap,
+            false);
     }
 
     /**
@@ -1750,10 +1564,12 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
      * @param deserializePortable Deserialize portable flag.
      * @param expiry Expiry policy.
      * @param skipVals Skip values flag.
-     * @param keepCacheObjects Keep cache objects
+     * @param keepCacheObjects Keep cache objects.
+     * @param canRemap Can remap flag.
+     * @param needVer If {@code true} returns values as tuples containing value and version.
      * @return Future.
      */
-    public <K1, V1> IgniteInternalFuture<Map<K1, V1>> getAllAsync0(@Nullable final Collection<KeyCacheObject> keys,
+    public final <K1, V1> IgniteInternalFuture<Map<K1, V1>> getAllAsync0(@Nullable final Collection<KeyCacheObject> keys,
         final boolean readThrough,
         boolean checkTx,
         @Nullable final UUID subjId,
@@ -1762,7 +1578,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
         @Nullable IgniteCacheExpiryPolicy expiry,
         final boolean skipVals,
         final boolean keepCacheObjects,
-        boolean canRemap
+        boolean canRemap,
+        final boolean needVer
         ) {
         if (F.isEmpty(keys))
             return new GridFinishedFuture<>(Collections.<K1, V1>emptyMap());
@@ -1782,14 +1599,14 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         if (tx == null || tx.implicit()) {
             try {
-                assert keys != null;
-
                 final AffinityTopologyVersion topVer = tx == null
                     ? (canRemap ? ctx.affinity().affinityTopologyVersion(): ctx.shared().exchange().readyAffinityVersion())
                     : tx.topologyVersion();
 
                 final Map<K1, V1> map = new GridLeanMap<>(keys.size());
 
+                final boolean storeEnabled = !skipVals && readThrough && ctx.readThrough();
+
                 Map<KeyCacheObject, GridCacheVersion> misses = null;
 
                 for (KeyCacheObject key : keys) {
@@ -1797,29 +1614,43 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                         GridCacheEntryEx entry = entryEx(key);
 
                         try {
-                            CacheObject val = entry.innerGet(null,
+                            T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(null,
                                 ctx.isSwapOrOffheapEnabled(),
-                                /*don't read-through*/false,
-                                /*fail-fast*/true,
                                 /*unmarshal*/true,
                                 /*update-metrics*/!skipVals,
                                 /*event*/!skipVals,
-                                /*temporary*/false,
                                 subjId,
                                 null,
                                 taskName,
                                 expiry);
 
-                            if (val == null) {
-                                GridCacheVersion ver = entry.version();
+                            if (res == null) {
+                                if (storeEnabled) {
+                                    GridCacheVersion ver = entry.version();
 
-                                if (misses == null)
-                                    misses = new GridLeanMap<>();
+                                    if (misses == null)
+                                        misses = new GridLeanMap<>();
 
-                                misses.put(key, ver);
+                                    misses.put(key, ver);
+                                }
+                                else
+                                    ctx.evicts().touch(entry, topVer);
                             }
                             else {
-                                ctx.addResult(map, key, val, skipVals, keepCacheObjects, deserializePortable, true);
+                                if (needVer) {
+                                    assert keepCacheObjects;
+
+                                    map.put((K1)key, (V1)new T2<>(res.get1(), res.get2()));
+                                }
+                                else {
+                                    ctx.addResult(map,
+                                        key,
+                                        res.get1(),
+                                        skipVals,
+                                        keepCacheObjects,
+                                        deserializePortable,
+                                        true);
+                                }
 
                                 if (tx == null || (!tx.implicit() && tx.isolation() == READ_COMMITTED))
                                     ctx.evicts().touch(entry, topVer);
@@ -1835,19 +1666,10 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                             if (log.isDebugEnabled())
                                 log.debug("Got removed entry in getAllAsync(..) method (will retry): " + key);
                         }
-                        catch (GridCacheFilterFailedException ignore) {
-                            if (log.isDebugEnabled())
-                                log.debug("Filter validation failed for entry: " + entry);
-
-                            if (tx == null || (!tx.implicit() && tx.isolation() == READ_COMMITTED))
-                                ctx.evicts().touch(entry, topVer);
-
-                            break; // While loop.
-                        }
                     }
                 }
 
-                if (!skipVals && misses != null && readThrough && ctx.readThrough()) {
+                if (storeEnabled && misses != null) {
                     final Map<KeyCacheObject, GridCacheVersion> loadKeys = misses;
 
                     final IgniteTxLocalAdapter tx0 = tx;
@@ -1858,9 +1680,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                         ctx.closures().callLocalSafe(ctx.projectSafe(new GPC<Map<K1, V1>>() {
                             @Override public Map<K1, V1> call() throws Exception {
                                 ctx.store().loadAll(null/*tx*/, loadKeys.keySet(), new CI2<KeyCacheObject, Object>() {
-                                    /** New version for all new entries. */
-                                    private GridCacheVersion nextVer;
-
                                     @Override public void apply(KeyCacheObject key, Object val) {
                                         GridCacheVersion ver = loadKeys.get(key);
 
@@ -1872,10 +1691,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                                             return;
                                         }
 
-                                        // Initialize next version.
-                                        if (nextVer == null)
-                                            nextVer = ctx.versions().next();
-
                                         loaded.add(key);
 
                                         CacheObject cacheVal = ctx.toCacheObject(val);
@@ -1884,22 +1699,33 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                                             GridCacheEntryEx entry = entryEx(key);
 
                                             try {
-                                                boolean set = entry.versionedValue(cacheVal, ver, nextVer);
+                                                GridCacheVersion verSet = entry.versionedValue(cacheVal, ver, null);
+
+                                                boolean set = verSet != null;
 
                                                 if (log.isDebugEnabled())
-                                                    log.debug("Set value loaded from store into entry [set=" + set +
-                                                        ", curVer=" + ver + ", newVer=" + nextVer + ", " +
+                                                    log.debug("Set value loaded from store into entry [" +
+                                                        "set=" + set +
+                                                        ", curVer=" + ver +
+                                                        ", newVer=" + verSet + ", " +
                                                         "entry=" + entry + ']');
 
                                                 // Don't put key-value pair into result map if value is null.
                                                 if (val != null) {
-                                                    ctx.addResult(map,
-                                                        key,
-                                                        cacheVal,
-                                                        skipVals,
-                                                        keepCacheObjects,
-                                                        deserializePortable,
-                                                        false);
+                                                    if (needVer) {
+                                                        assert keepCacheObjects;
+
+                                                        map.put((K1)key, (V1)new T2<>(cacheVal, set ? verSet : ver));
+                                                    }
+                                                    else {
+                                                        ctx.addResult(map,
+                                                            key,
+                                                            cacheVal,
+                                                            skipVals,
+                                                            keepCacheObjects,
+                                                            deserializePortable,
+                                                            false);
+                                                    }
                                                 }
 
                                                 if (tx0 == null || (!tx0.implicit() &&
@@ -1992,9 +1818,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             }
         }
         else {
+            assert !needVer;
+
             return asyncOp(tx, new AsyncOp<Map<K1, V1>>(keys) {
                 @Override public IgniteInternalFuture<Map<K1, V1>> op(IgniteTxLocalAdapter tx) {
-                    return tx.getAllAsync(ctx, keys, null, deserializePortable, skipVals, false, !readThrough);
+                    return tx.getAllAsync(ctx, keys, deserializePortable, skipVals, false, !readThrough);
                 }
             });
         }
@@ -2028,7 +1856,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         V prevVal = syncOp(new SyncOp<V>(true) {
             @Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                return (V)tx.putAllAsync(ctx, F.t(key, val), true, null, -1, filter).get().value();
+                return (V)tx.putAllAsync(ctx, F.t(key, val), true, filter).get().value();
             }
 
             @Override public String toString() {
@@ -2083,7 +1911,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         return asyncOp(new AsyncOp<V>() {
             @Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
-                return tx.putAllAsync(ctx, F.t(key, val), true, null, -1, filter)
+                return tx.putAllAsync(ctx, F.t(key, val), true, filter)
                     .chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
             }
 
@@ -2122,7 +1950,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         Boolean stored = syncOp(new SyncOp<Boolean>(true) {
             @Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, filter).get().success();
+                return tx.putAllAsync(ctx, F.t(key, val), false, filter).get().success();
             }
 
             @Override public String toString() {
@@ -2414,7 +2242,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         return asyncOp(new AsyncOp<Boolean>() {
             @Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
-                return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, filter).chain(
+                return tx.putAllAsync(ctx, F.t(key, val), false, filter).chain(
                     (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>) RET2FLAG);
             }
 
@@ -2449,7 +2277,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         return syncOp(new SyncOp<V>(true) {
             @Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                return (V)tx.putAllAsync(ctx, F.t(key, val), true, null, -1, ctx.noValArray()).get().value();
+                return (V)tx.putAllAsync(ctx, F.t(key, val), true, ctx.noValArray()).get().value();
             }
 
             @Override public String toString() {
@@ -2473,7 +2301,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
             @Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
-                return tx.putAllAsync(ctx, F.t(key, val), true, null, -1, ctx.noValArray())
+                return tx.putAllAsync(ctx, F.t(key, val), true, ctx.noValArray())
                     .chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>) RET2VAL);
             }
 
@@ -2503,7 +2331,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         Boolean stored = syncOp(new SyncOp<Boolean>(true) {
             @Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, ctx.noValArray()).get().success();
+                return tx.putAllAsync(ctx, F.t(key, val), false, ctx.noValArray()).get().success();
             }
 
             @Override public String toString() {
@@ -2532,7 +2360,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         IgniteInternalFuture<Boolean> fut = asyncOp(new AsyncOp<Boolean>() {
             @Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
-                return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, ctx.noValArray()).chain(
+                return tx.putAllAsync(ctx, F.t(key, val), false, ctx.noValArray()).chain(
                     (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
             }
 
@@ -2558,7 +2386,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         return syncOp(new SyncOp<V>(true) {
             @Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                return (V)tx.putAllAsync(ctx, F.t(key, val), true, null, -1, ctx.hasValArray()).get().value();
+                return (V)tx.putAllAsync(ctx, F.t(key, val), true, ctx.hasValArray()).get().value();
             }
 
             @Override public String toString() {
@@ -2582,7 +2410,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
             @Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
-                return tx.putAllAsync(ctx, F.t(key, val), true, null, -1, ctx.hasValArray()).chain(
+                return tx.putAllAsync(ctx, F.t(key, val), true, ctx.hasValArray()).chain(
                     (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
             }
 
@@ -2608,7 +2436,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         return syncOp(new SyncOp<Boolean>(true) {
             @Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, ctx.hasValArray()).get().success();
+                return tx.putAllAsync(ctx, F.t(key, val), false, ctx.hasValArray()).get().success();
             }
 
             @Override public String toString() {
@@ -2628,7 +2456,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         return asyncOp(new AsyncOp<Boolean>() {
             @Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
-                return tx.putAllAsync(ctx, F.t(key, val), false, null, -1, ctx.hasValArray()).chain(
+                return tx.putAllAsync(ctx, F.t(key, val), false, ctx.hasValArray()).chain(
                     (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>) RET2FLAG);
             }
 
@@ -2655,7 +2483,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                 if (ctx.deploymentEnabled())
                     ctx.deploy().registerClass(oldVal);
 
-                return tx.putAllAsync(ctx, F.t(key, newVal), false, null, -1, ctx.equalsValArray(oldVal)).get()
+                return tx.putAllAsync(ctx, F.t(key, newVal), false, ctx.equalsValArray(oldVal)).get()
                     .success();
             }
 
@@ -2692,7 +2520,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                     }
                 }
 
-                return tx.putAllAsync(ctx, F.t(key, newVal), false, null, -1, ctx.equalsValArray(oldVal)).chain(
+                return tx.putAllAsync(ctx, F.t(key, newVal), false, ctx.equalsValArray(oldVal)).chain(
                     (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
             }
 
@@ -2723,7 +2551,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         syncOp(new SyncInOp(m.size() == 1) {
             @Override public void inOp(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                tx.putAllAsync(ctx, m, false, null, -1, CU.empty0()).get();
+                tx.putAllAsync(ctx, m, false, CU.empty0()).get();
             }
 
             @Override public String toString() {
@@ -2747,7 +2575,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         return asyncOp(new AsyncInOp(m.keySet()) {
             @Override public IgniteInternalFuture<?> inOp(IgniteTxLocalAdapter tx) {
-                return tx.putAllAsync(ctx, m, false, null, -1, CU.empty0()).chain(RET2NULL);
+                return tx.putAllAsync(ctx, m, false, CU.empty0()).chain(RET2NULL);
             }
 
             @Override public String toString() {
@@ -2769,7 +2597,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         V prevVal = syncOp(new SyncOp<V>(true) {
             @Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                V ret = tx.removeAllAsync(ctx, Collections.singletonList(key), null, true, CU.empty0()).get().value();
+                V ret = tx.removeAllAsync(ctx,
+                    Collections.singletonList(key),
+                    /*retval*/true,
+                    CU.empty0(),
+                    /*singleRmv*/false).get().value();
 
                 if (ctx.config().getInterceptor() != null)
                     return (V)ctx.config().getInterceptor().onBeforeRemove(new CacheEntryImpl(key, ret)).get2();
@@ -2802,8 +2634,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
         IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
             @Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
                 // TODO should we invoke interceptor here?
-                return tx.removeAllAsync(ctx, Collections.singletonList(key), null, true, CU.empty0())
-                    .chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>) RET2VAL);
+                return tx.removeAllAsync(ctx,
+                    Collections.singletonList(key),
+                    /*retval*/true,
+                    CU.empty0(),
+                    /*singleRmv*/false).chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
             }
 
             @Override public String toString() {
@@ -2849,7 +2684,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         syncOp(new SyncInOp(keys.size() == 1) {
             @Override public void inOp(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                tx.removeAllAsync(ctx, keys, null, false, CU.empty0()).get();
+                tx.removeAllAsync(ctx,
+                    keys,
+                    /*retval*/false,
+                    CU.empty0(),
+                    /*singleRmv*/false).get();
             }
 
             @Override public String toString() {
@@ -2875,7 +2714,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         IgniteInternalFuture<Object> fut = asyncOp(new AsyncInOp(keys) {
             @Override public IgniteInternalFuture<?> inOp(IgniteTxLocalAdapter tx) {
-                return tx.removeAllAsync(ctx, keys, null, false, CU.empty0()).chain(RET2NULL);
+                return tx.removeAllAsync(ctx,
+                    keys,
+                    /*retval*/false,
+                    CU.empty0(),
+                    /*singleRmv*/false).chain(RET2NULL);
             }
 
             @Override public String toString() {
@@ -2902,7 +2745,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         boolean rmv = syncOp(new SyncOp<Boolean>(true) {
             @Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
-                return tx.removeAllAsync(ctx, Collections.singletonList(key), null, false, CU.empty0()).get().success();
+                return tx.removeAllAsync(ctx,
+                    Collections.singletonList(key),
+                    /*retval*/false,
+                    CU.empty0(),
+                    /*singleRmv*/true).get().success();
             }
 
             @Override public String toString() {
@@ -2940,7 +2787,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         IgniteInternalFuture<Boolean> fut = asyncOp(new AsyncOp<Boolean>() {
             @Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
-                return tx.removeAllAsync(ctx, Collections.singletonList(key), null, false, filter).chain(
+                return tx.removeAllAsync(ctx,
+                    Collections.singletonList(key),
+                    /*retval*/false,
+                    filter,
+                    /*singleRmv*/true).chain(
                     (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
             }
 
@@ -2970,9 +2821,9 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
                 return tx.removeAllAsync(ctx,
                     Collections.singletonList(key),
-                    null,
-                    true,
-                    ctx.equalsValArray(val)).get();
+                    /*retval*/true,
+                    ctx.equalsValArray(val),
+                    /*singleRmv*/false).get();
             }
 
             @Override public String toString() {
@@ -3037,8 +2888,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                 return tx.putAllAsync(ctx,
                         F.t(key, newVal),
                         true,
-                        null,
-                        -1,
                         ctx.equalsValArray(oldVal)).get();
             }
 
@@ -3066,13 +2915,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                     return new GridFinishedFuture<>(e);
                 }
 
-                IgniteInternalFuture<GridCacheReturn> fut = (IgniteInternalFuture)tx.removeAllAsync(ctx,
+                return (IgniteInternalFuture)tx.removeAllAsync(ctx,
                     Collections.singletonList(key),
-                    null,
-                    true,
-                    ctx.equalsValArray(val));
-
-                return fut;
+                    /*retval*/true,
+                    ctx.equalsValArray(val),
+                    /*singleRmv*/false);
             }
 
             @Override public String toString() {
@@ -3100,14 +2947,10 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                     return new GridFinishedFuture<>(e);
                 }
 
-                IgniteInternalFuture<GridCacheReturn> fut = (IgniteInternalFuture)tx.putAllAsync(ctx,
+                return (IgniteInternalFuture)tx.putAllAsync(ctx,
                     F.t(key, newVal),
                     true,
-                    null,
-                    -1,
                     ctx.equalsValArray(oldVal));
-
-                return fut;
             }
 
             @Override public String toString() {
@@ -3135,8 +2978,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                 if (ctx.deploymentEnabled())
                     ctx.deploy().registerClass(val);
 
-                return tx.removeAllAsync(ctx, Collections.singletonList(key), null, false,
-                    ctx.equalsValArray(val)).get().success();
+                return tx.removeAllAsync(ctx,
+                    Collections.singletonList(key),
+                    /*retval*/false,
+                    ctx.equalsValArray(val),
+                    /*singleRmv*/false).get().success();
             }
 
             @Override public String toString() {
@@ -3175,8 +3021,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                     }
                 }
 
-                return tx.removeAllAsync(ctx, Collections.singletonList(key), null, false,
-                    ctx.equalsValArray(val)).chain(
+                return tx.removeAllAsync(ctx,
+                    Collections.singletonList(key),
+                    /*retval*/false,
+                    ctx.equalsValArray(val),
+                    /*singleRmv*/false).chain(
                     (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
             }
 
@@ -3200,7 +3049,11 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         return asyncOp(new AsyncInOp(keys) {
             @Override public IgniteInternalFuture<?> inOp(IgniteTxLocalAdapter tx) {
-                return tx.removeAllAsync(ctx, keys, null, false, null);
+                return tx.removeAllAsync(ctx,
+                    keys,
+                    /*retval*/false,
+                    null,
+                    /*singleRmv*/false);
             }
 
             @Override public String toString() {
@@ -4579,7 +4432,6 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
             !ctx.config().isReadFromBackup(),
             /*skip tx*/false,
             null,
-            null,
             taskName,
             deserializePortable,
             false,
@@ -4741,41 +4593,34 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
         boolean deserializePortable)
         throws IgniteCheckedException, GridCacheEntryRemovedException
     {
-        try {
-            CacheObject val = entry.innerGet(
-                null,
-                false,
-                false,
-                false,
-                true,
-                false,
-                false,
-                false,
-                null,
-                null,
-                null,
-                null);
-
-            if (val == null)
-                return null;
+        CacheObject val = entry.innerGet(
+            null,
+            false,
+            false,
+            false,
+            true,
+            false,
+            false,
+            false,
+            null,
+            null,
+            null,
+            null);
 
-            KeyCacheObject key = entry.key();
+        if (val == null)
+            return null;
 
-            Object key0 = key.value(ctx.cacheObjectContext(), true);
-            Object val0 = val.value(ctx.cacheObjectContext(), true);
+        KeyCacheObject key = entry.key();
 
-            if (deserializePortable) {
-                key0 = ctx.unwrapPortableIfNeeded(key0, true);
-                val0 = ctx.unwrapPortableIfNeeded(val0, true);
-            }
+        Object key0 = key.value(ctx.cacheObjectContext(), true);
+        Object val0 = val.value(ctx.cacheObjectContext(), true);
 
-            return new CacheEntryImpl<>((K)key0, (V)val0, entry.version());
+        if (deserializePortable) {
+            key0 = ctx.unwrapPortableIfNeeded(key0, true);
+            val0 = ctx.unwrapPortableIfNeeded(val0, true);
         }
-        catch (GridCacheFilterFailedException ignore) {
-            assert false;
 
-            return null;
-        }
+        return new CacheEntryImpl<>((K)key0, (V)val0, entry.version());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
index 430590a..50b01c8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
@@ -33,6 +33,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersionedEntryEx;
 import org.apache.ignite.internal.processors.dr.GridDrType;
 import org.apache.ignite.internal.util.lang.GridTuple3;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -286,12 +287,10 @@ public interface GridCacheEntryEx {
      * @param subjId Subject ID initiated this read.
      * @param transformClo Transform closure to record event.
      * @param taskName Task name.
-     *      together with getting the value is an atomic operation.
      * @param expiryPlc Expiry policy.
      * @return Cached value.
      * @throws IgniteCheckedException If loading value failed.
      * @throws GridCacheEntryRemovedException If entry was removed.
-     * @throws GridCacheFilterFailedException If filter failed.
      */
     @Nullable public CacheObject innerGet(@Nullable IgniteInternalTx tx,
         boolean readSwap,
@@ -305,7 +304,33 @@ public interface GridCacheEntryEx {
         Object transformClo,
         String taskName,
         @Nullable IgniteCacheExpiryPolicy expiryPlc)
-        throws IgniteCheckedException, GridCacheEntryRemovedException, GridCacheFilterFailedException;
+        throws IgniteCheckedException, GridCacheEntryRemovedException;
+
+    /**
+     * @param tx Cache transaction.
+     * @param readSwap Flag indicating whether to check swap memory.
+     * @param unmarshal Unmarshal flag.
+     * @param updateMetrics If {@code true} then metrics should be updated.
+     * @param evt Flag to signal event notification.
+     * @param subjId Subject ID initiated this read.
+     * @param transformClo Transform closure to record event.
+     * @param taskName Task name.
+     * @param expiryPlc Expiry policy.
+     * @return Cached value and entry version.
+     * @throws IgniteCheckedException If loading value failed.
+     * @throws GridCacheEntryRemovedException If entry was removed.
+     */
+    @Nullable public T2<CacheObject, GridCacheVersion> innerGetVersioned(
+        IgniteInternalTx tx,
+        boolean readSwap,
+        boolean unmarshal,
+        boolean updateMetrics,
+        boolean evt,
+        UUID subjId,
+        Object transformClo,
+        String taskName,
+        @Nullable IgniteCacheExpiryPolicy expiryPlc)
+        throws IgniteCheckedException, GridCacheEntryRemovedException;
 
     /**
      * Reloads entry from underlying storage.
@@ -334,6 +359,7 @@ public interface GridCacheEntryEx {
      * @param explicitVer Explicit version (if any).
      * @param subjId Subject ID initiated this update.
      * @param taskName Task name.
+     * @param dhtVer Dht version for near cache entry.
      * @return Tuple containing success flag and old value. If success is {@code false},
      *      then value is {@code null}.
      * @throws IgniteCheckedException If storing value failed.
@@ -355,7 +381,8 @@ public interface GridCacheEntryEx {
         long drExpireTime,
         @Nullable GridCacheVersion explicitVer,
         @Nullable UUID subjId,
-        String taskName
+        String taskName,
+        @Nullable GridCacheVersion dhtVer
     ) throws IgniteCheckedException, GridCacheEntryRemovedException;
 
     /**
@@ -372,6 +399,7 @@ public interface GridCacheEntryEx {
      * @param explicitVer Explicit version (if any).
      * @param subjId Subject ID initiated this update.
      * @param taskName Task name.
+     * @param dhtVer Dht version for near cache entry.
      * @return Tuple containing success flag and old value. If success is {@code false},
      *      then value is {@code null}.
      * @throws IgniteCheckedException If remove failed.
@@ -390,7 +418,8 @@ public interface GridCacheEntryEx {
         GridDrType drType,
         @Nullable GridCacheVersion explicitVer,
         @Nullable UUID subjId,
-        String taskName
+        String taskName,
+        @Nullable GridCacheVersion dhtVer
     ) throws IgniteCheckedException, GridCacheEntryRemovedException;
 
     /**
@@ -409,6 +438,7 @@ public interface GridCacheEntryEx {
      * @param primary If update is performed on primary node (the one which assigns version).
      * @param checkVer Whether update should check current version and ignore update if current version is
      *      greater than passed in.
+     * @param topVer Topology version.
      * @param filter Optional filter to check.
      * @param drType DR type.
      * @param conflictTtl Conflict TTL (if any).
@@ -510,12 +540,17 @@ public interface GridCacheEntryEx {
      *
      * @param tx Cache transaction.
      * @param timeout Timeout for lock acquisition.
+     * @param serOrder Version for serializable transactions ordering.
+     * @param serReadVer Optional read entry version for optimistic serializable transaction.
      * @return {@code True} if lock was acquired, {@code false} otherwise.
      * @throws GridCacheEntryRemovedException If this entry is obsolete.
      * @throws GridDistributedLockCancelledException If lock has been cancelled.
      */
-    public boolean tmLock(IgniteInternalTx tx, long timeout) throws GridCacheEntryRemovedException,
-        GridDistributedLockCancelledException;
+    public boolean tmLock(IgniteInternalTx tx,
+        long timeout,
+        @Nullable GridCacheVersion serOrder,
+        @Nullable GridCacheVersion serReadVer)
+        throws GridCacheEntryRemovedException, GridDistributedLockCancelledException;
 
     /**
      * Unlocks acquired lock.
@@ -566,6 +601,15 @@ public interface GridCacheEntryEx {
     public GridCacheVersion version() throws GridCacheEntryRemovedException;
 
     /**
+     * Checks if there was read/write conflict in serializable transaction.
+     *
+     * @param serReadVer Version read in serializable transaction.
+     * @return {@code True} if version check passed.
+     * @throws GridCacheEntryRemovedException If entry has been removed.
+     */
+    public boolean checkSerializableReadVersion(GridCacheVersion serReadVer) throws GridCacheEntryRemovedException;
+
+    /**
      * Peeks into entry without loading value or updating statistics.
      *
      * @param heap Read from heap flag.
@@ -653,11 +697,11 @@ public interface GridCacheEntryEx {
      * @param val New value.
      * @param curVer Version to match or {@code null} if match is not required.
      * @param newVer Version to set.
-     * @return {@code True} if versioned matched.
+     * @return Non null version if value was set.
      * @throws IgniteCheckedException If index could not be updated.
      * @throws GridCacheEntryRemovedException If entry was removed.
      */
-    public boolean versionedValue(CacheObject val,
+    public GridCacheVersion versionedValue(CacheObject val,
         @Nullable GridCacheVersion curVer,
         @Nullable GridCacheVersion newVer)
         throws IgniteCheckedException, GridCacheEntryRemovedException;

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 4bf0aa1..2111594 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -37,12 +37,14 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo;
 import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry;
 import org.apache.ignite.internal.processors.cache.extras.GridCacheEntryExtras;
 import org.apache.ignite.internal.processors.cache.extras.GridCacheMvccEntryExtras;
 import org.apache.ignite.internal.processors.cache.extras.GridCacheObsoleteEntryExtras;
 import org.apache.ignite.internal.processors.cache.extras.GridCacheTtlEntryExtras;
 import org.apache.ignite.internal.processors.cache.query.GridCacheQueryManager;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxLocalAdapter;
 import org.apache.ignite.internal.processors.cache.version.GridCachePlainVersionedEntry;
@@ -59,6 +61,7 @@ import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.T3;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
@@ -673,7 +676,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         String taskName,
         @Nullable IgniteCacheExpiryPolicy expirePlc)
         throws IgniteCheckedException, GridCacheEntryRemovedException {
-        return innerGet0(tx,
+        return (CacheObject)innerGet0(tx,
             readSwap,
             readThrough,
             evt,
@@ -683,12 +686,39 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
             subjId,
             transformClo,
             taskName,
-            expirePlc);
+            expirePlc,
+            false);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public T2<CacheObject, GridCacheVersion> innerGetVersioned(
+        IgniteInternalTx tx,
+        boolean readSwap,
+        boolean unmarshal,
+        boolean updateMetrics,
+        boolean evt,
+        UUID subjId,
+        Object transformClo,
+        String taskName,
+        @Nullable IgniteCacheExpiryPolicy expiryPlc)
+        throws IgniteCheckedException, GridCacheEntryRemovedException {
+        return (T2<CacheObject, GridCacheVersion>)innerGet0(tx,
+            readSwap,
+            false,
+            evt,
+            unmarshal,
+            updateMetrics,
+            false,
+            subjId,
+            transformClo,
+            taskName,
+            expiryPlc,
+            true);
     }
 
     /** {@inheritDoc} */
     @SuppressWarnings({"unchecked", "RedundantTypeArguments", "TooBroadScope"})
-    private CacheObject innerGet0(IgniteInternalTx tx,
+    private Object innerGet0(IgniteInternalTx tx,
         boolean readSwap,
         boolean readThrough,
         boolean evt,
@@ -698,8 +728,11 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         UUID subjId,
         Object transformClo,
         String taskName,
-        @Nullable IgniteCacheExpiryPolicy expiryPlc)
+        @Nullable IgniteCacheExpiryPolicy expiryPlc,
+        boolean retVer)
         throws IgniteCheckedException, GridCacheEntryRemovedException {
+        assert !(retVer && readThrough);
+
         // Disable read-through if there is no store.
         if (readThrough && !cctx.readThrough())
             readThrough = false;
@@ -710,6 +743,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         CacheObject ret = null;
 
         GridCacheVersion startVer;
+        GridCacheVersion resVer = null;
 
         boolean expired = false;
 
@@ -840,11 +874,18 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
 
             if (ret != null && expiryPlc != null)
                 updateTtl(expiryPlc);
+
+            if (retVer) {
+                resVer = isNear() ? ((GridNearCacheEntry)this).dhtVersion() : this.ver;
+
+                if (resVer == null)
+                    ret = null;
+            }
         }
 
         if (ret != null)
             // If return value is consistent, then done.
-            return ret;
+            return retVer ? new T2<>(ret, resVer) : ret;
 
         boolean loadedFromStore = false;
 
@@ -906,6 +947,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
             }
         }
 
+        assert ret == null || !retVer;
+
         return ret;
     }
 
@@ -1015,7 +1058,8 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         long drExpireTime,
         @Nullable GridCacheVersion explicitVer,
         @Nullable UUID subjId,
-        String taskName
+        String taskName,
+        @Nullable GridCacheVersion dhtVer
     ) throws IgniteCheckedException, GridCacheEntryRemovedException {
         CacheObject old;
 
@@ -1035,6 +1079,14 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         synchronized (this) {
             checkObsolete();
 
+            if (isNear()) {
+                assert dhtVer != null;
+
+                // It is possible that 'get' could load more recent value.
+                if (!((GridNearCacheEntry)this).recordDhtVersion(dhtVer))
+                    return new GridCacheUpdateTxResult(false, null);
+            }
+
             assert tx == null || (!tx.local() && tx.onePhaseCommit()) || tx.ownsLock(this) :
                 "Transaction does not own lock for update [entry=" + this + ", tx=" + tx + ']';
 
@@ -1169,8 +1221,9 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         GridDrType drType,
         @Nullable GridCacheVersion explicitVer,
         @Nullable UUID subjId,
-        String taskName
-    ) throws IgniteCheckedException, GridCacheEntryRemovedException {
+        String taskName,
+        @Nullable GridCacheVersion dhtVer
+        ) throws IgniteCheckedException, GridCacheEntryRemovedException {
         assert cctx.transactional();
 
         CacheObject old;
@@ -1194,6 +1247,14 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         synchronized (this) {
             checkObsolete();
 
+            if (isNear()) {
+                assert dhtVer != null;
+
+                // It is possible that 'get' could load more recent value.
+                if (!((GridNearCacheEntry)this).recordDhtVersion(dhtVer))
+                    return new GridCacheUpdateTxResult(false, null);
+            }
+
             assert tx == null || (!tx.local() && tx.onePhaseCommit()) || tx.ownsLock(this) :
                     "Transaction does not own lock for remove[entry=" + this + ", tx=" + tx + ']';
 
@@ -2549,6 +2610,13 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
     }
 
     /**
+     * @return {@code True} if this entry should not be evicted from cache.
+     */
+    protected boolean evictionDisabled() {
+        return false;
+    }
+
+    /**
      * <p>
      * Note that {@link #onMarkedObsolete()} should always be called after this method
      * returns {@code true}.
@@ -2560,6 +2628,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
     protected final boolean markObsolete0(GridCacheVersion ver, boolean clear) {
         assert Thread.holdsLock(this);
 
+        if (evictionDisabled()) {
+            assert !obsolete() : this;
+
+            return false;
+        }
+
         GridCacheVersion obsoleteVer = obsoleteVersionExtras();
 
         if (ver != null) {
@@ -2790,6 +2864,25 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         return ver;
     }
 
+    /** {@inheritDoc} */
+    @Override public synchronized boolean checkSerializableReadVersion(GridCacheVersion serReadVer)
+        throws GridCacheEntryRemovedException {
+        checkObsolete();
+
+        if (!serReadVer.equals(ver)) {
+            boolean empty = isStartVersion() || deletedUnlocked();
+
+            if (serReadVer.equals(IgniteTxEntry.SER_READ_EMPTY_ENTRY_VER))
+                return empty;
+            else if (serReadVer.equals(IgniteTxEntry.SER_READ_NOT_EMPTY_VER))
+                return !empty;
+
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * Gets hash value for the entry key.
      *
@@ -3115,16 +3208,22 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
     }
 
     /** {@inheritDoc} */
-    @Override public synchronized boolean versionedValue(CacheObject val,
+    @Override public synchronized GridCacheVersion versionedValue(CacheObject val,
         GridCacheVersion curVer,
         GridCacheVersion newVer)
         throws IgniteCheckedException, GridCacheEntryRemovedException {
+
         checkObsolete();
 
         if (curVer == null || curVer.equals(ver)) {
             if (val != this.val) {
+                GridCacheMvcc mvcc = mvccExtras();
+
+                if (mvcc != null && !mvcc.isEmpty())
+                    return null;
+
                 if (newVer == null)
-                    newVer = nextVersion();
+                    newVer = cctx.versions().next();
 
                 CacheObject old = rawGetOrUnmarshalUnlocked(false);
 
@@ -3144,12 +3243,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
 
                 // Version does not change for load ops.
                 update(val, expTime, ttl, newVer);
-            }
 
-            return true;
+                return newVer;
+            }
         }
 
-        return false;
+        return null;
     }
 
     /**
@@ -3683,6 +3782,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         try {
             if (F.isEmptyOrNulls(filter)) {
                 synchronized (this) {
+                    if (evictionDisabled()) {
+                        assert !obsolete();
+
+                        return false;
+                    }
+
                     if (obsoleteVersionExtras() != null)
                         return true;
 
@@ -3727,6 +3832,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
                         return false;
 
                     synchronized (this) {
+                        if (evictionDisabled()) {
+                            assert !obsolete();
+
+                            return false;
+                        }
+
                         if (obsoleteVersionExtras() != null)
                             return true;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
index c2102bd..12583ad 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.cache;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.Deque;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -53,6 +54,32 @@ public final class GridCacheMvcc {
     /** Logger. */
     private static volatile IgniteLogger log;
 
+    /** */
+    private static final Comparator<GridCacheVersion> SER_VER_COMPARATOR = new Comparator<GridCacheVersion>() {
+        @Override public int compare(GridCacheVersion ver1, GridCacheVersion ver2) {
+            long time1 = ver1.globalTime();
+            long time2 = ver2.globalTime();
+
+            if (time1 == time2) {
+                int nodeOrder1 = ver1.nodeOrder();
+                int nodeOrder2 = ver2.nodeOrder();
+
+                if (nodeOrder1 == nodeOrder2) {
+                    long order1 = ver1.order();
+                    long order2 = ver2.order();
+
+                    assert order1 != order2;
+
+                    return order1 > order2 ? 1 : -1;
+                }
+                else
+                    return nodeOrder1 > nodeOrder2 ? 1 : -1;
+            }
+            else
+                return time1 > time2 ? 1 : -1;
+        }
+    };
+
     /** Cache context. */
     @GridToStringExclude
     private final GridCacheContext<?, ?> cctx;
@@ -160,8 +187,9 @@ public final class GridCacheMvcc {
 
     /**
      * @param cand Candidate to add.
+     * @return {@code False} if failed to add candidate and transaction should be cancelled.
      */
-    private void add0(GridCacheMvccCandidate cand) {
+    private boolean add0(GridCacheMvccCandidate cand) {
         assert cand != null;
 
         // Local.
@@ -171,31 +199,59 @@ public final class GridCacheMvcc {
 
             if (!cand.nearLocal()) {
                 if (!locs.isEmpty()) {
-                    GridCacheMvccCandidate c = locs.getFirst();
+                    if (cand.serializable()) {
+                        GridCacheMvccCandidate last = locs.getLast();
+
+                        if (!last.serializable())
+                            return false;
+
+                        GridCacheVersion lastOrder = last.serializableOrder();
+
+                        assert lastOrder != null : last;
+
+                        GridCacheVersion candOrder = cand.serializableOrder();
 
-                    if (c.owner()) {
+                        assert candOrder != null : cand;
+
+                        int cmp = SER_VER_COMPARATOR.compare(lastOrder, candOrder);
+
+                        assert cmp != 0;
+
+                        if (cmp > 0)
+                            return false;
+
+                        locs.addLast(cand);
+
+                        return true;
+                    }
+
+                    GridCacheMvccCandidate first = locs.getFirst();
+
+                    if (first.owner()) {
                         // If reentry, add at the beginning. Note that
                         // no reentry happens for DHT-local candidates.
-                        if (!cand.dhtLocal() && c.threadId() == cand.threadId()) {
+                        if (!cand.dhtLocal() && first.threadId() == cand.threadId()) {
+                            assert !first.serializable();
+
                             cand.setOwner();
                             cand.setReady();
                             cand.setReentry();
 
                             locs.addFirst(cand);
 
-                            return;
+                            return true;
                         }
                     }
 
                     // Iterate in reverse order.
                     for (ListIterator<GridCacheMvccCandidate> it = locs.listIterator(locs.size()); it.hasPrevious(); ) {
-                        c = it.previous();
+                        GridCacheMvccCandidate c = it.previous();
 
                         assert !c.version().equals(cand.version()) : "Versions can't match [existing=" + c +
                             ", new=" + cand + ']';
 
-                        // Add after the owner.
-                        if (c.owner()) {
+                        // Add after the owner or serializable tx.
+                        if (c.owner() || c.serializable()) {
                             // Threads are checked above.
                             assert cand.dhtLocal() || c.threadId() != cand.threadId();
 
@@ -204,7 +260,7 @@ public final class GridCacheMvcc {
 
                             it.add(cand);
 
-                            return;
+                            return true;
                         }
 
                         // If not the owner, add after the lesser version.
@@ -214,7 +270,7 @@ public final class GridCacheMvcc {
 
                             it.add(cand);
 
-                            return;
+                            return true;
                         }
                     }
                 }
@@ -228,6 +284,8 @@ public final class GridCacheMvcc {
         }
         // Remote.
         else {
+            assert !cand.serializable() : cand;
+
             if (rmts == null)
                 rmts = new LinkedList<>();
 
@@ -241,12 +299,14 @@ public final class GridCacheMvcc {
                 if (cand.owner())
                     cur.setOwner();
 
-                return;
+                return true;
             }
 
             // Either list is empty or candidate is last.
             rmts.add(cand);
         }
+
+        return true;
     }
 
     /**
@@ -456,6 +516,7 @@ public final class GridCacheMvcc {
             threadId,
             ver,
             timeout,
+            /*serializable order*/null,
             reenter,
             tx,
             implicitSingle,
@@ -470,6 +531,7 @@ public final class GridCacheMvcc {
      * @param threadId Thread ID.
      * @param ver Lock version.
      * @param timeout Lock acquisition timeout.
+     * @param serOrder Version for serializable transactions ordering.
      * @param reenter Reentry flag ({@code true} if reentry is allowed).
      * @param tx Transaction flag.
      * @param implicitSingle Implicit flag.
@@ -484,6 +546,7 @@ public final class GridCacheMvcc {
         long threadId,
         GridCacheVersion ver,
         long timeout,
+        @Nullable GridCacheVersion serOrder,
         boolean reenter,
         boolean tx,
         boolean implicitSingle,
@@ -528,12 +591,23 @@ public final class GridCacheMvcc {
             tx,
             implicitSingle,
             /*near-local*/false,
-            dhtLoc
+            dhtLoc,
+            serOrder
         );
 
-        cctx.mvcc().addLocal(cand);
+        if (serOrder == null) {
+            cctx.mvcc().addLocal(cand);
 
-        add0(cand);
+            boolean add = add0(cand);
+
+            assert add : cand;
+        }
+        else {
+            if (!add0(cand))
+                return null;
+
+            cctx.mvcc().addLocal(cand);
+        }
 
         return cand;
     }
@@ -575,7 +649,8 @@ public final class GridCacheMvcc {
             tx,
             implicitSingle,
             nearLoc,
-            false
+            false,
+            null
         );
 
         addRemote(cand);
@@ -596,11 +671,28 @@ public final class GridCacheMvcc {
      * @param implicitSingle Implicit flag.
      * @return Add remote candidate.
      */
-    public GridCacheMvccCandidate addNearLocal(GridCacheEntryEx parent, UUID nodeId,
-        @Nullable UUID otherNodeId, long threadId, GridCacheVersion ver, long timeout, boolean tx,
+    public GridCacheMvccCandidate addNearLocal(GridCacheEntryEx parent,
+        UUID nodeId,
+        @Nullable UUID otherNodeId,
+        long threadId,
+        GridCacheVersion ver,
+        long timeout,
+        boolean tx,
         boolean implicitSingle) {
-        GridCacheMvccCandidate cand = new GridCacheMvccCandidate(parent, nodeId, otherNodeId, null, threadId, ver,
-            timeout, /*local*/true, /*reentry*/false, tx, implicitSingle, /*near loc*/true, /*dht loc*/false);
+        GridCacheMvccCandidate cand = new GridCacheMvccCandidate(parent,
+            nodeId,
+            otherNodeId,
+            null,
+            threadId,
+            ver,
+            timeout,
+            /*local*/true,
+            /*reentry*/false,
+            tx,
+            implicitSingle,
+            /*near loc*/true,
+            /*dht loc*/false,
+            null);
 
         add0(cand);
 
@@ -855,9 +947,22 @@ public final class GridCacheMvcc {
         }
 
         if (locs != null) {
+            boolean first = true;
+
             for (ListIterator<GridCacheMvccCandidate> it = locs.listIterator(); it.hasNext(); ) {
                 GridCacheMvccCandidate cand = it.next();
 
+                if (first && cand.serializable()) {
+                    if (cand.owner() || !cand.ready())
+                        return;
+
+                    cand.setOwner();
+
+                    return;
+                }
+
+                first = false;
+
                 if (cand.owner())
                     return;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java
index f19a054..aba8318 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java
@@ -126,6 +126,9 @@ public class GridCacheMvccCandidate implements Externalizable,
     @GridToStringInclude
     private transient volatile GridCacheVersion ownerVer;
 
+    /** */
+    private GridCacheVersion serOrder;
+
     /**
      * Empty constructor required by {@link Externalizable}.
      */
@@ -147,6 +150,7 @@ public class GridCacheMvccCandidate implements Externalizable,
      * @param singleImplicit Single-key-implicit-transaction flag.
      * @param nearLoc Near-local flag.
      * @param dhtLoc DHT local flag.
+     * @param serOrder Version for serializable transactions ordering.
      */
     public GridCacheMvccCandidate(
         GridCacheEntryEx parent,
@@ -161,7 +165,9 @@ public class GridCacheMvccCandidate implements Externalizable,
         boolean tx,
         boolean singleImplicit,
         boolean nearLoc,
-        boolean dhtLoc) {
+        boolean dhtLoc,
+        @Nullable GridCacheVersion serOrder
+    ) {
         assert nodeId != null;
         assert ver != null;
         assert parent != null;
@@ -173,6 +179,7 @@ public class GridCacheMvccCandidate implements Externalizable,
         this.threadId = threadId;
         this.ver = ver;
         this.timeout = timeout;
+        this.serOrder = serOrder;
 
         mask(LOCAL, loc);
         mask(REENTRY, reentry);
@@ -244,7 +251,8 @@ public class GridCacheMvccCandidate implements Externalizable,
             tx(),
             singleImplicit(),
             nearLocal(),
-            dhtLocal());
+            dhtLocal(),
+            serializableOrder());
 
         reentry.topVer = topVer;
 
@@ -452,6 +460,20 @@ public class GridCacheMvccCandidate implements Externalizable,
     }
 
     /**
+     * @return Serializable transaction flag.
+     */
+    public boolean serializable() {
+        return serOrder != null;
+    }
+
+    /**
+     * @return Version for serializable transactions ordering.
+     */
+    @Nullable public GridCacheVersion serializableOrder() {
+        return serOrder;
+    }
+
+    /**
      * @return {@code True} if this candidate is a reentry.
      */
     public boolean reentry() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 578ad6c..5bf4ac7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -139,7 +139,6 @@ import static org.apache.ignite.internal.IgniteComponentType.JTA;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CONSISTENCY_CHECK_SKIPPED;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_TX_CONFIG;
 import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isNearEnabled;
-import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
 
 /**
  * Cache processor.
@@ -398,15 +397,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
             throw new IgniteCheckedException("Cannot start cache in PRIVATE or ISOLATED deployment mode: " +
                 ctx.config().getDeploymentMode());
 
-        if (!c.getTransactionConfiguration().isTxSerializableEnabled() &&
-            c.getTransactionConfiguration().getDefaultTxIsolation() == SERIALIZABLE)
-            U.warn(log,
-                "Serializable transactions are disabled while default transaction isolation is SERIALIZABLE " +
-                    "(most likely misconfiguration - either update 'isTxSerializableEnabled' or " +
-                    "'defaultTxIsolationLevel' properties) for cache: " + U.maskName(cc.getName()),
-                "Serializable transactions are disabled while default transaction isolation is SERIALIZABLE " +
-                    "for cache: " + U.maskName(cc.getName()));
-
         if (cc.isWriteBehindEnabled()) {
             if (cfgStore == null)
                 throw new IgniteCheckedException("Cannot enable write-behind (writer or store is not provided) " +
@@ -619,9 +609,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         sharedCtx = createSharedContext(ctx, CU.startStoreSessionListeners(ctx,
             ctx.config().getCacheStoreSessionListenerFactories()));
 
-        ctx.performance().add("Disable serializable transactions (set 'txSerializableEnabled' to false)",
-            !ctx.config().getTransactionConfiguration().isTxSerializableEnabled());
-
         for (int i = 0; i < cfgs.length; i++) {
             if (ctx.config().isDaemon() && !CU.isMarshallerCache(cfgs[i].getName()))
                 continue;

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
index d4f0d6c..a138d30 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheObject;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
@@ -742,7 +743,10 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean tmLock(IgniteInternalTx tx, long timeout)
+    @Override public boolean tmLock(IgniteInternalTx tx,
+        long timeout,
+        @Nullable GridCacheVersion serOrder,
+        GridCacheVersion serReadVer)
         throws GridCacheEntryRemovedException, GridDistributedLockCancelledException {
         if (tx.local())
             // Null is returned if timeout is negative and there is other lock owner.
@@ -751,8 +755,8 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry {
                 tx.xidVersion(),
                 tx.topologyVersion(),
                 timeout,
-                false,
-                true,
+                /*reenter*/false,
+                /*tx*/true,
                 tx.implicitSingle()) != null;
 
         try {
@@ -762,7 +766,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry {
                 tx.threadId(),
                 tx.xidVersion(),
                 tx.timeout(),
-                true,
+                /*tx*/true,
                 tx.implicitSingle(),
                 tx.ownedVersion(txKey())
             );


[25/31] ignite git commit: ignite-1607 Implemented deadlock-free optimistic serializable tx mode

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/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 f22e753..82e5f2a 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
@@ -31,12 +31,12 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
+import javax.cache.Cache;
 import javax.cache.CacheException;
 import javax.cache.expiry.Duration;
 import javax.cache.expiry.ExpiryPolicy;
 import javax.cache.processor.EntryProcessor;
 import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -57,7 +57,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.processors.cache.GridCacheUpdateTxResult;
 import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
 import org.apache.ignite.internal.processors.cache.KeyCacheObject;
-import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry;
+import org.apache.ignite.internal.processors.cache.distributed.dht.colocated.GridDhtDetachedCacheEntry;
 import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo;
 import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
@@ -73,6 +73,7 @@ import org.apache.ignite.internal.util.future.GridEmbeddedFuture;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.lang.GridClosureException;
+import org.apache.ignite.internal.util.lang.GridInClosure3;
 import org.apache.ignite.internal.util.lang.GridTuple;
 import org.apache.ignite.internal.util.tostring.GridToStringBuilder;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -85,10 +86,8 @@ import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.CU;
-import org.apache.ignite.internal.util.typedef.internal.GPC;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiClosure;
-import org.apache.ignite.lang.IgniteBiInClosure;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteClosure;
 import org.apache.ignite.plugin.security.SecurityPermission;
@@ -105,6 +104,8 @@ import static org.apache.ignite.internal.processors.cache.GridCacheOperation.REA
 import static org.apache.ignite.internal.processors.cache.GridCacheOperation.RELOAD;
 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.processors.cache.transactions.IgniteTxEntry.SER_READ_EMPTY_ENTRY_VER;
+import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry.SER_READ_NOT_EMPTY_VER;
 import static org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE;
 import static org.apache.ignite.internal.processors.dr.GridDrType.DR_PRIMARY;
 import static org.apache.ignite.transactions.TransactionState.COMMITTED;
@@ -424,46 +425,126 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     }
 
     /** {@inheritDoc} */
-    @Override public IgniteInternalFuture<Boolean> loadMissing(
+    @Override public IgniteInternalFuture<Void> loadMissing(
         final GridCacheContext cacheCtx,
         final boolean readThrough,
         boolean async,
         final Collection<KeyCacheObject> keys,
-        boolean deserializePortable,
         boolean skipVals,
-        final IgniteBiInClosure<KeyCacheObject, Object> c
+        boolean needVer,
+        final GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c
     ) {
-        if (!async) {
-            try {
-                if (!readThrough || !cacheCtx.readThrough()) {
-                    for (KeyCacheObject key : keys)
-                        c.apply(key, null);
+        assert cacheCtx.isLocal() : cacheCtx.name();
 
-                    return new GridFinishedFuture<>(false);
-                }
+        if (!readThrough || !cacheCtx.readThrough()) {
+            for (KeyCacheObject key : keys)
+                c.apply(key, null, SER_READ_EMPTY_ENTRY_VER);
 
-                return new GridFinishedFuture<>(
-                    cacheCtx.store().loadAll(this, keys, c));
-            }
-            catch (IgniteCheckedException e) {
-                return new GridFinishedFuture<>(e);
-            }
+            return new GridFinishedFuture<>();
         }
-        else {
-            return cctx.kernalContext().closure().callLocalSafe(
-                new GPC<Boolean>() {
-                    @Override public Boolean call() throws Exception {
-                        if (!readThrough || !cacheCtx.readThrough()) {
-                            for (KeyCacheObject key : keys)
-                                c.apply(key, null);
-
-                            return false;
+
+        try {
+            IgniteCacheExpiryPolicy expiryPlc = accessPolicy(cacheCtx, keys);
+
+            Map<KeyCacheObject, GridCacheVersion> misses = null;
+
+            for (KeyCacheObject key : keys) {
+                while (true) {
+                    IgniteTxEntry txEntry = entry(cacheCtx.txKey(key));
+
+                    GridCacheEntryEx entry = txEntry == null ? cacheCtx.cache().entryEx(key) :
+                        txEntry.cached();
+
+                    if (entry == null)
+                        continue;
+
+                    try {
+                        T2<CacheObject, GridCacheVersion> res = entry.innerGetVersioned(this,
+                            /*readSwap*/true,
+                            /*unmarshal*/true,
+                            /*update-metrics*/!skipVals,
+                            /*event*/!skipVals,
+                            CU.subjectId(this, cctx),
+                            null,
+                            resolveTaskName(),
+                            expiryPlc);
+
+                        if (res == null) {
+                            if (misses == null)
+                                misses = new LinkedHashMap<>();
+
+                            misses.put(key, entry.version());
                         }
+                        else
+                            c.apply(key, skipVals ? true : res.get1(), res.get2());
 
-                        return cacheCtx.store().loadAll(IgniteTxLocalAdapter.this, keys, c);
+                        break;
                     }
-                },
-                true);
+                    catch (GridCacheEntryRemovedException ignore) {
+                        if (log.isDebugEnabled())
+                            log.debug("Got removed entry, will retry: " + key);
+
+                        if (txEntry != null)
+                            txEntry.cached(cacheCtx.cache().entryEx(key));
+                    }
+                }
+            }
+
+            if (misses != null) {
+                final Map<KeyCacheObject, GridCacheVersion> misses0 = misses;
+
+                cacheCtx.store().loadAll(this, misses.keySet(), new CI2<KeyCacheObject, Object>() {
+                    @Override public void apply(KeyCacheObject key, Object val) {
+                        GridCacheVersion ver = misses0.remove(key);
+
+                        assert ver != null : key;
+
+                        if (val != null) {
+                            CacheObject cacheVal = cacheCtx.toCacheObject(val);
+
+                            while (true) {
+                                GridCacheEntryEx entry = cacheCtx.cache().entryEx(key);
+
+                                try {
+                                    GridCacheVersion setVer = entry.versionedValue(cacheVal, ver, null);
+
+                                    boolean set = setVer != null;
+
+                                    if (set)
+                                        ver = setVer;
+
+                                    if (log.isDebugEnabled())
+                                        log.debug("Set value loaded from store into entry [set=" + set +
+                                            ", curVer=" + ver + ", newVer=" + setVer + ", " +
+                                            "entry=" + entry + ']');
+
+                                    break;
+                                }
+                                catch (GridCacheEntryRemovedException ignore) {
+                                    if (log.isDebugEnabled())
+                                        log.debug("Got removed entry, (will retry): " + entry);
+                                }
+                                catch (IgniteCheckedException e) {
+                                    // Wrap errors (will be unwrapped).
+                                    throw new GridClosureException(e);
+                                }
+                            }
+                        }
+                        else
+                            ver = SER_READ_EMPTY_ENTRY_VER;
+
+                        c.apply(key, val, ver);
+                    }
+                });
+
+                for (KeyCacheObject key : misses0.keySet())
+                    c.apply(key, null, SER_READ_EMPTY_ENTRY_VER);
+            }
+
+            return new GridFinishedFuture<>();
+        }
+        catch (IgniteCheckedException e) {
+            return new GridFinishedFuture<>(e);
         }
     }
 
@@ -834,13 +915,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                     IgniteBiTuple<GridCacheOperation, CacheObject> res = applyTransformClosures(txEntry,
                                         true);
 
+                                    GridCacheVersion dhtVer = null;
+
                                     // For near local transactions we must record DHT version
                                     // in order to keep near entries on backup nodes until
                                     // backup remote transaction completes.
                                     if (cacheCtx.isNear()) {
                                         if (txEntry.op() == CREATE || txEntry.op() == UPDATE ||
                                             txEntry.op() == DELETE || txEntry.op() == TRANSFORM)
-                                            ((GridNearCacheEntry)cached).recordDhtVersion(txEntry.dhtVersion());
+                                            dhtVer = txEntry.dhtVersion();
 
                                         if ((txEntry.op() == CREATE || txEntry.op() == UPDATE) &&
                                             txEntry.conflictExpireTime() == CU.EXPIRE_TIME_CALCULATE) {
@@ -921,6 +1004,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                         txEntry.conflictVersion(explicitVer);
                                     }
 
+                                    if (dhtVer == null)
+                                        dhtVer = explicitVer != null ? explicitVer : writeVersion();
+
                                     if (op == CREATE || op == UPDATE) {
                                         GridCacheUpdateTxResult updRes = cached.innerSet(
                                             this,
@@ -938,9 +1024,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                             txEntry.conflictExpireTime(),
                                             cached.isNear() ? null : explicitVer,
                                             CU.subjectId(this, cctx),
-                                            resolveTaskName());
+                                            resolveTaskName(),
+                                            dhtVer);
 
-                                        if (nearCached != null && updRes.success())
+                                        if (nearCached != null && updRes.success()) {
                                             nearCached.innerSet(
                                                 null,
                                                 eventNodeId(),
@@ -957,7 +1044,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                                 txEntry.conflictExpireTime(),
                                                 null,
                                                 CU.subjectId(this, cctx),
-                                                resolveTaskName());
+                                                resolveTaskName(),
+                                                dhtVer);
+                                        }
                                     }
                                     else if (op == DELETE) {
                                         GridCacheUpdateTxResult updRes = cached.innerRemove(
@@ -973,9 +1062,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                             cached.detached()  ? DR_NONE : drType,
                                             cached.isNear() ? null : explicitVer,
                                             CU.subjectId(this, cctx),
-                                            resolveTaskName());
+                                            resolveTaskName(),
+                                            dhtVer);
 
-                                        if (nearCached != null && updRes.success())
+                                        if (nearCached != null && updRes.success()) {
                                             nearCached.innerRemove(
                                                 null,
                                                 eventNodeId(),
@@ -989,7 +1079,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                                 DR_NONE,
                                                 null,
                                                 CU.subjectId(this, cctx),
-                                                resolveTaskName());
+                                                resolveTaskName(),
+                                                dhtVer);
+                                        }
                                     }
                                     else if (op == RELOAD) {
                                         cached.innerReload();
@@ -1180,14 +1272,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                 commitErr.get());
         }
 
+        if (near()) {
+            // Must evict near entries before rolling back from
+            // transaction manager, so they will be removed from cache.
+            for (IgniteTxEntry e : allEntries())
+                evictNearEntry(e, false);
+        }
+
         if (doneFlag.compareAndSet(false, true)) {
             try {
-                if (near())
-                    // Must evict near entries before rolling back from
-                    // transaction manager, so they will be removed from cache.
-                    for (IgniteTxEntry e : allEntries())
-                        evictNearEntry(e, false);
-
                 cctx.tm().rollbackTx(this);
 
                 if (!internal()) {
@@ -1228,12 +1321,19 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     }
 
     /**
+     * @param entry Entry.
+     * @return {@code True} if local node is current primary for given entry.
+     */
+    private boolean primaryLocal(GridCacheEntryEx entry) {
+        return entry.context().affinity().primary(cctx.localNode(), entry.partition(), AffinityTopologyVersion.NONE);
+    }
+
+    /**
      * Checks if there is a cached or swapped value for
-     * {@link #getAllAsync(GridCacheContext, Collection, GridCacheEntryEx, boolean, boolean, boolean, boolean)} method.
+     * {@link #getAllAsync(GridCacheContext, Collection, boolean, boolean, boolean, boolean)} method.
      *
      * @param cacheCtx Cache context.
      * @param keys Key to enlist.
-     * @param cached Cached entry, if called from entry wrapper.
      * @param expiryPlc Explicitly specified expiry policy for entry.
      * @param map Return map.
      * @param missed Map of missed keys.
@@ -1249,7 +1349,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     private <K, V> Collection<KeyCacheObject> enlistRead(
         final GridCacheContext cacheCtx,
         Collection<KeyCacheObject> keys,
-        @Nullable GridCacheEntryEx cached,
         @Nullable ExpiryPolicy expiryPlc,
         Map<K, V> map,
         Map<KeyCacheObject, GridCacheVersion> missed,
@@ -1261,7 +1360,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     ) throws IgniteCheckedException {
         assert !F.isEmpty(keys);
         assert keysCnt == keys.size();
-        assert cached == null || F.first(keys).equals(cached.key());
 
         cacheCtx.checkSecurity(SecurityPermission.CACHE_READ);
 
@@ -1271,11 +1369,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
 
         AffinityTopologyVersion topVer = topologyVersion();
 
+        boolean needReadVer = serializable() && optimistic();
+
         // In this loop we cover only read-committed or optimistic transactions.
         // Transactions that are pessimistic and not read-committed are covered
         // outside of this loop.
         for (KeyCacheObject key : keys) {
-            if (pessimistic() && !readCommitted() && !skipVals)
+            if ((pessimistic() || needReadVer) && !readCommitted() && !skipVals)
                 addActiveCache(cacheCtx);
 
             IgniteTxKey txKey = cacheCtx.txKey(key);
@@ -1337,13 +1437,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
 
                             break;
                         }
-                        catch (GridCacheFilterFailedException e) {
-                            if (log.isDebugEnabled())
-                                log.debug("Filter validation failed for entry: " + txEntry);
-
-                            if (!readCommitted())
-                                txEntry.readValue(e.<V>value());
-                        }
                         catch (GridCacheEntryRemovedException ignored) {
                             txEntry.cached(entryEx(cacheCtx, txEntry.txKey(), topVer));
                         }
@@ -1359,38 +1452,49 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                     lockKeys.add(key);
 
                 while (true) {
-                    GridCacheEntryEx entry;
-
-                    if (cached != null) {
-                        entry = cached;
-
-                        cached = null;
-                    }
-                    else
-                        entry = entryEx(cacheCtx, txKey, topVer);
+                    GridCacheEntryEx entry = entryEx(cacheCtx, txKey, topVer);
 
                     try {
                         GridCacheVersion ver = entry.version();
 
                         CacheObject val = null;
+                        GridCacheVersion readVer = null;
 
                         if (!pessimistic() || readCommitted() && !skipVals) {
                             IgniteCacheExpiryPolicy accessPlc =
                                 optimistic() ? accessPolicy(cacheCtx, txKey, expiryPlc) : null;
 
-                            // This call will check for filter.
-                            val = entry.innerGet(this,
-                                /*swap*/true,
-                                /*no read-through*/false,
-                                /*fail-fast*/true,
-                                /*unmarshal*/true,
-                                /*metrics*/true,
-                                /*event*/true,
-                                /*temporary*/false,
-                                CU.subjectId(this, cctx),
-                                null,
-                                resolveTaskName(),
-                                accessPlc);
+                            if (needReadVer) {
+                                T2<CacheObject, GridCacheVersion> res = primaryLocal(entry) ?
+                                    entry.innerGetVersioned(this,
+                                        /*swap*/true,
+                                        /*unmarshal*/true,
+                                        /*metrics*/true,
+                                        /*event*/true,
+                                        CU.subjectId(this, cctx),
+                                        null,
+                                        resolveTaskName(),
+                                        accessPlc) : null;
+
+                                if (res != null) {
+                                    val = res.get1();
+                                    readVer = res.get2();
+                                }
+                            }
+                            else {
+                                val = entry.innerGet(this,
+                                    /*swap*/true,
+                                    /*no read-through*/false,
+                                    /*fail-fast*/true,
+                                    /*unmarshal*/true,
+                                    /*metrics*/true,
+                                    /*event*/true,
+                                    /*temporary*/false,
+                                    CU.subjectId(this, cctx),
+                                    null,
+                                    resolveTaskName(),
+                                    accessPlc);
+                            }
 
                             if (val != null) {
                                 cacheCtx.addResult(map,
@@ -1424,8 +1528,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
 
                             // As optimization, mark as checked immediately
                             // for non-pessimistic if value is not null.
-                            if (val != null && !pessimistic())
+                            if (val != null && !pessimistic()) {
                                 txEntry.markValid();
+
+                                if (needReadVer) {
+                                    assert readVer != null;
+
+                                    txEntry.serializableReadVersion(readVer);
+                                }
+                            }
                         }
 
                         break; // While.
@@ -1434,34 +1545,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                         if (log.isDebugEnabled())
                             log.debug("Got removed entry in transaction getAllAsync(..) (will retry): " + key);
                     }
-                    catch (GridCacheFilterFailedException e) {
-                        if (log.isDebugEnabled())
-                            log.debug("Filter validation failed for entry: " + entry);
-
-                        if (!readCommitted()) {
-                            // Value for which failure occurred.
-                            CacheObject val = e.value();
-
-                            txEntry = addEntry(READ,
-                                val,
-                                null,
-                                null,
-                                entry,
-                                expiryPlc,
-                                CU.empty0(),
-                                false,
-                                -1L,
-                                -1L,
-                                null,
-                                skipStore);
-
-                            // Mark as checked immediately for non-pessimistic.
-                            if (val != null && !pessimistic())
-                                txEntry.markValid();
-                        }
-
-                        break; // While loop.
-                    }
                     finally {
                         if (cacheCtx.isNear() && entry != null && readCommitted()) {
                             if (cacheCtx.affinity().belongs(cacheCtx.localNode(), entry.partition(), topVer)) {
@@ -1492,6 +1575,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     }
 
     /**
+     * @param cacheCtx Cache context.
+     * @param keys Keys.
+     * @return Expiry policy.
+     */
+    protected IgniteCacheExpiryPolicy accessPolicy(GridCacheContext cacheCtx, Collection<KeyCacheObject> keys) {
+        return null;
+    }
+
+    /**
      * Adds skipped key.
      *
      * @param skipped Skipped set (possibly {@code null}).
@@ -1512,12 +1604,11 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
 
     /**
      * Loads all missed keys for
-     * {@link #getAllAsync(GridCacheContext, Collection, GridCacheEntryEx, boolean, boolean, boolean, boolean)} method.
+     * {@link #getAllAsync(GridCacheContext, Collection, boolean, boolean, boolean, boolean)} method.
      *
      * @param cacheCtx Cache context.
      * @param map Return map.
      * @param missedMap Missed keys.
-     * @param redos Keys to retry.
      * @param deserializePortable Deserialize portable flag.
      * @param skipVals Skip values flag.
      * @param keepCacheObjects Keep cache objects flag.
@@ -1528,55 +1619,25 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
         final GridCacheContext cacheCtx,
         final Map<K, V> map,
         final Map<KeyCacheObject, GridCacheVersion> missedMap,
-        @Nullable final Collection<KeyCacheObject> redos,
         final boolean deserializePortable,
         final boolean skipVals,
         final boolean keepCacheObjects,
         final boolean skipStore
     ) {
-        assert redos != null || pessimistic();
-
         if (log.isDebugEnabled())
             log.debug("Loading missed values for missed map: " + missedMap);
 
-        final Collection<KeyCacheObject> loaded = new HashSet<>();
+        final boolean needReadVer = serializable() && optimistic();
 
         return new GridEmbeddedFuture<>(
-            new C2<Boolean, Exception, Map<K, V>>() {
-                @Override public Map<K, V> apply(Boolean b, Exception e) {
+            new C2<Void, Exception, Map<K, V>>() {
+                @Override public Map<K, V> apply(Void v, Exception e) {
                     if (e != null) {
                         setRollbackOnly();
 
                         throw new GridClosureException(e);
                     }
 
-                    if (!b && !readCommitted()) {
-                        // There is no store - we must mark the entries.
-                        for (KeyCacheObject key : missedMap.keySet()) {
-                            IgniteTxEntry txEntry = entry(cacheCtx.txKey(key));
-
-                            if (txEntry != null)
-                                txEntry.markValid();
-                        }
-                    }
-
-                    if (readCommitted()) {
-                        Collection<KeyCacheObject> notFound = new HashSet<>(missedMap.keySet());
-
-                        notFound.removeAll(loaded);
-
-                        // In read-committed mode touch entries that have just been read.
-                        for (KeyCacheObject key : notFound) {
-                            IgniteTxEntry txEntry = entry(cacheCtx.txKey(key));
-
-                            GridCacheEntryEx entry = txEntry == null ? cacheCtx.cache().peekEx(key) :
-                                txEntry.cached();
-
-                            if (entry != null)
-                                cacheCtx.evicts().touch(entry, topologyVersion());
-                        }
-                    }
-
                     return map;
                 }
             },
@@ -1585,13 +1646,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                 !skipStore,
                 false,
                 missedMap.keySet(),
-                deserializePortable,
                 skipVals,
-                new CI2<KeyCacheObject, Object>() {
-                    /** */
-                    private GridCacheVersion nextVer;
-
-                    @Override public void apply(KeyCacheObject key, Object val) {
+                needReadVer,
+                new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
+                    @Override public void apply(KeyCacheObject key, Object val, GridCacheVersion loadVer) {
                         if (isRollbackOnly()) {
                             if (log.isDebugEnabled())
                                 log.debug("Ignoring loaded value for read because transaction was rolled back: " +
@@ -1600,15 +1658,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                             return;
                         }
 
-                        GridCacheVersion ver = missedMap.get(key);
-
-                        if (ver == null) {
-                            if (log.isDebugEnabled())
-                                log.debug("Value from storage was never asked for [key=" + key + ", val=" + val + ']');
-
-                            return;
-                        }
-
                         CacheObject cacheVal = cacheCtx.toCacheObject(val);
 
                         CacheObject visibleVal = cacheVal;
@@ -1625,90 +1674,42 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                 visibleVal = txEntry.applyEntryProcessors(visibleVal);
                         }
 
-                        // In pessimistic mode we hold the lock, so filter validation
-                        // should always be valid.
-                        if (pessimistic())
-                            ver = null;
-
-                        // Initialize next version.
-                        if (nextVer == null)
-                            nextVer = cctx.versions().next(topologyVersion());
-
-                        while (true) {
-                            assert txEntry != null || readCommitted() || skipVals;
-
-                            GridCacheEntryEx e = txEntry == null ? entryEx(cacheCtx, txKey) : txEntry.cached();
-
-                            try {
-                                // Must initialize to true since even if filter didn't pass,
-                                // we still record the transaction value.
-                                boolean set;
-
-                                try {
-                                    set = e.versionedValue(cacheVal, ver, nextVer);
-                                }
-                                catch (GridCacheEntryRemovedException ignore) {
-                                    if (log.isDebugEnabled())
-                                        log.debug("Got removed entry in transaction getAll method " +
-                                            "(will try again): " + e);
-
-                                    if (pessimistic() && !readCommitted() && !isRollbackOnly()) {
-                                        U.error(log, "Inconsistent transaction state (entry got removed while " +
-                                            "holding lock) [entry=" + e + ", tx=" + IgniteTxLocalAdapter.this + "]");
-
-                                        setRollbackOnly();
-
-                                        return;
-                                    }
-
-                                    if (txEntry != null)
-                                        txEntry.cached(entryEx(cacheCtx, txKey));
-
-                                    continue; // While loop.
-                                }
-
-                                // In pessimistic mode, we should always be able to set.
-                                assert set || !pessimistic();
-
-                                if (readCommitted() || skipVals) {
-                                    cacheCtx.evicts().touch(e, topologyVersion());
+                        assert txEntry != null || readCommitted() || skipVals;
 
-                                    if (visibleVal != null) {
-                                        cacheCtx.addResult(map,
-                                            key,
-                                            visibleVal,
-                                            skipVals,
-                                            keepCacheObjects,
-                                            deserializePortable,
-                                            false);
-                                    }
-                                }
-                                else {
-                                    assert txEntry != null;
+                        GridCacheEntryEx e = txEntry == null ? entryEx(cacheCtx, txKey) : txEntry.cached();
 
-                                    txEntry.setAndMarkValid(cacheVal);
+                        if (readCommitted() || skipVals) {
+                            cacheCtx.evicts().touch(e, topologyVersion());
 
-                                    if (visibleVal != null) {
-                                        cacheCtx.addResult(map,
-                                            key,
-                                            visibleVal,
-                                            skipVals,
-                                            keepCacheObjects,
-                                            deserializePortable,
-                                            false);
-                                    }
-                                }
+                            if (visibleVal != null) {
+                                cacheCtx.addResult(map,
+                                    key,
+                                    visibleVal,
+                                    skipVals,
+                                    keepCacheObjects,
+                                    deserializePortable,
+                                    false);
+                            }
+                        }
+                        else {
+                            assert txEntry != null;
 
-                                loaded.add(key);
+                            txEntry.setAndMarkValid(cacheVal);
 
-                                if (log.isDebugEnabled())
-                                    log.debug("Set value loaded from store into entry from transaction [set=" + set +
-                                        ", matchVer=" + ver + ", newVer=" + nextVer + ", entry=" + e + ']');
+                            if (needReadVer) {
+                                assert loadVer != null;
 
-                                break; // While loop.
+                                txEntry.serializableReadVersion(loadVer);
                             }
-                            catch (IgniteCheckedException ex) {
-                                throw new IgniteException("Failed to put value for cache entry: " + e, ex);
+
+                            if (visibleVal != null) {
+                                cacheCtx.addResult(map,
+                                    key,
+                                    visibleVal,
+                                    skipVals,
+                                    keepCacheObjects,
+                                    deserializePortable,
+                                    false);
                             }
                         }
                     }
@@ -1720,7 +1721,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     @Override public <K, V> IgniteInternalFuture<Map<K, V>> getAllAsync(
         final GridCacheContext cacheCtx,
         Collection<KeyCacheObject> keys,
-        @Nullable GridCacheEntryEx cached,
         final boolean deserializePortable,
         final boolean skipVals,
         final boolean keepCacheObjects,
@@ -1747,7 +1747,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
 
             final Collection<KeyCacheObject> lockKeys = enlistRead(cacheCtx,
                 keys,
-                cached,
                 expiryPlc,
                 retMap,
                 missed,
@@ -1850,20 +1849,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
 
                                     txEntry.cached(entryEx(cacheCtx, txKey));
                                 }
-                                catch (GridCacheFilterFailedException e) {
-                                    // Failed value for the filter.
-                                    CacheObject val = e.value();
-
-                                    if (val != null) {
-                                        // If filter fails after lock is acquired, we don't reload,
-                                        // regardless if value is null or not.
-                                        missed.remove(cacheKey);
-
-                                        txEntry.setAndMarkValid(val);
-                                    }
-
-                                    break; // While.
-                                }
                             }
                         }
 
@@ -1871,7 +1856,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                             return checkMissed(cacheCtx,
                                 retMap,
                                 missed,
-                                null,
                                 deserializePortable,
                                 skipVals,
                                 keepCacheObjects,
@@ -1920,8 +1904,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
             else {
                 assert optimistic() || readCommitted() || skipVals;
 
-                final Collection<KeyCacheObject> redos = new ArrayList<>();
-
                 if (!missed.isEmpty()) {
                     if (!readCommitted())
                         for (Iterator<KeyCacheObject> it = missed.keySet().iterator(); it.hasNext(); ) {
@@ -1937,67 +1919,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                     if (missed.isEmpty())
                         return new GridFinishedFuture<>(retMap);
 
-                    IgniteInternalFuture<Map<K, V>> fut0 = checkMissed(cacheCtx,
+                    return checkMissed(cacheCtx,
                         retMap,
                         missed,
-                        redos,
                         deserializePortable,
                         skipVals,
                         keepCacheObjects,
                         skipStore);
-
-                    return new GridEmbeddedFuture<>(
-                        // First future.
-                        fut0,
-                        // Closure that returns another future, based on result from first.
-                        new PMC<Map<K, V>>() {
-                            @Override public IgniteInternalFuture<Map<K, V>> postMiss(Map<K, V> map) {
-                                if (redos.isEmpty())
-                                    return new GridFinishedFuture<>(
-                                        Collections.<K, V>emptyMap());
-
-                                if (log.isDebugEnabled())
-                                    log.debug("Starting to future-recursively get values for keys: " + redos);
-
-                                // Future recursion.
-                                return getAllAsync(cacheCtx,
-                                    redos,
-                                    null,
-                                    deserializePortable,
-                                    skipVals,
-                                    true,
-                                    skipStore);
-                            }
-                        },
-                        // Finalize.
-                        new FinishClosure<Map<K, V>>() {
-                            @Override Map<K, V> finish(Map<K, V> loaded) {
-                                for (Map.Entry<K, V> entry : loaded.entrySet()) {
-                                    KeyCacheObject cacheKey = (KeyCacheObject)entry.getKey();
-
-                                    IgniteTxEntry txEntry = entry(cacheCtx.txKey(cacheKey));
-
-                                    CacheObject val = (CacheObject)entry.getValue();
-
-                                    if (!readCommitted())
-                                        txEntry.readValue(val);
-
-                                    if (!F.isEmpty(txEntry.entryProcessors()))
-                                        val = txEntry.applyEntryProcessors(val);
-
-                                    cacheCtx.addResult(retMap,
-                                        cacheKey,
-                                        val,
-                                        skipVals,
-                                        keepCacheObjects,
-                                        deserializePortable,
-                                        false);
-                                }
-
-                                return retMap;
-                            }
-                        }
-                    );
                 }
 
                 return new GridFinishedFuture<>(retMap);
@@ -2016,8 +1944,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
         GridCacheContext cacheCtx,
         Map<? extends K, ? extends V> map,
         boolean retval,
-        @Nullable GridCacheEntryEx cached,
-        long ttl,
         CacheEntryPredicate[] filter
     ) {
         return (IgniteInternalFuture<GridCacheReturn>)putAllAsync0(cacheCtx,
@@ -2026,7 +1952,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
             null,
             null,
             retval,
-            cached,
             filter);
     }
 
@@ -2041,7 +1966,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
             null,
             drMap,
             false,
-            null,
             null);
     }
 
@@ -2058,7 +1982,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
             invokeArgs,
             null,
             true,
-            null,
             null);
     }
 
@@ -2067,20 +1990,24 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
         GridCacheContext cacheCtx,
         Map<KeyCacheObject, GridCacheVersion> drMap
     ) {
-        return removeAllAsync0(cacheCtx, null, drMap, null, false, null);
+        return removeAllAsync0(cacheCtx, null, drMap, false, null, false);
     }
 
     /**
      * Checks filter for non-pessimistic transactions.
      *
-     * @param cached Cached entry.
+     * @param cctx Cache context.
+     * @param key Key.
+     * @param val Value.
      * @param filter Filter to check.
      * @return {@code True} if passed or pessimistic.
-     * @throws IgniteCheckedException If failed.
      */
-    private <K, V> boolean filter(GridCacheEntryEx cached,
-        CacheEntryPredicate[] filter) throws IgniteCheckedException {
-        return pessimistic() || (optimistic() && implicit()) || cached.context().isAll(cached, filter);
+    private boolean filter(
+        GridCacheContext cctx,
+        KeyCacheObject key,
+        CacheObject val,
+        CacheEntryPredicate[] filter) {
+        return pessimistic() || (optimistic() && implicit()) || isAll(cctx, key, val, filter);
     }
 
     /**
@@ -2088,7 +2015,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
      *
      * @param cacheCtx Cache context.
      * @param keys Keys to enlist.
-     * @param cached Cached entry.
      * @param expiryPlc Explicitly specified expiry policy for entry.
      * @param implicit Implicit flag.
      * @param lookup Value lookup map ({@code null} for remove).
@@ -2102,28 +2028,28 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
      * @param drPutMap DR put map (optional).
      * @param drRmvMap DR remove map (optional).
      * @param skipStore Skip store flag.
+     * @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
      * @return Future with skipped keys (the ones that didn't pass filter for pessimistic transactions).
      */
-    protected <K, V> IgniteInternalFuture<Set<KeyCacheObject>> enlistWrite(
+    private <K, V> IgniteInternalFuture<Set<KeyCacheObject>> enlistWrite(
         final GridCacheContext cacheCtx,
         Collection<?> keys,
-        @Nullable GridCacheEntryEx cached,
         @Nullable ExpiryPolicy expiryPlc,
         boolean implicit,
         @Nullable Map<?, ?> lookup,
         @Nullable Map<?, EntryProcessor<K, V, Object>> invokeMap,
         @Nullable Object[] invokeArgs,
-        boolean retval,
+        final boolean retval,
         boolean lockOnly,
-        CacheEntryPredicate[] filter,
+        final CacheEntryPredicate[] filter,
         final GridCacheReturn ret,
         Collection<KeyCacheObject> enlisted,
         @Nullable Map<KeyCacheObject, GridCacheDrInfo> drPutMap,
         @Nullable Map<KeyCacheObject, GridCacheVersion> drRmvMap,
-        boolean skipStore
+        boolean skipStore,
+        final boolean singleRmv
     ) {
-        assert cached == null || keys.size() == 1;
-        assert cached == null || F.first(keys).equals(cached.key());
+        assert retval || invokeMap == null;
 
         try {
             addActiveCache(cacheCtx);
@@ -2138,6 +2064,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
 
         Set<KeyCacheObject> missedForLoad = null;
 
+        final boolean hasFilters = !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter);
+        final boolean needVal = singleRmv || retval || hasFilters;
+        final boolean needReadVer = needVal && (serializable() && optimistic());
+
         try {
             // Set transform flag for transaction.
             if (invokeMap != null)
@@ -2194,19 +2124,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                 // First time access.
                 if (txEntry == null) {
                     while (true) {
-                        GridCacheEntryEx entry = null;
+                        GridCacheEntryEx entry = entryEx(cacheCtx, txKey, topologyVersion());
 
                         try {
-                            if (cached != null) {
-                                entry = cached;
-
-                                cached = null;
-                            }
-                            else {
-                                entry = entryEx(cacheCtx, txKey, topologyVersion());
-
-                                entry.unswap(false);
-                            }
+                            entry.unswap(false);
 
                             // Check if lock is being explicitly acquired by the same thread.
                             if (!implicit && cctx.kernalContext().config().isCacheSanityCheckEnabled() &&
@@ -2217,45 +2138,57 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                     ", locNodeId=" + cctx.localNodeId() + ']');
 
                             CacheObject old = null;
-
-                            boolean readThrough = !skipStore && !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter);
+                            GridCacheVersion readVer = null;
 
                             if (optimistic() && !implicit()) {
                                 try {
-                                    // Should read through if filter is specified.
-                                    old = entry.innerGet(this,
-                                        /*swap*/false,
-                                        /*read-through*/readThrough && cacheCtx.loadPreviousValue(),
-                                        /*fail-fast*/false,
-                                        /*unmarshal*/retval,
-                                        /*metrics*/retval,
-                                        /*events*/retval,
-                                        /*temporary*/false,
-                                        CU.subjectId(this, cctx),
-                                        entryProcessor,
-                                        resolveTaskName(),
-                                        null);
+                                    if (needReadVer) {
+                                        T2<CacheObject, GridCacheVersion> res = primaryLocal(entry) ?
+                                            entry.innerGetVersioned(this,
+                                                /*swap*/false,
+                                                /*unmarshal*/retval,
+                                                /*metrics*/retval,
+                                                /*events*/retval,
+                                                CU.subjectId(this, cctx),
+                                                entryProcessor,
+                                                resolveTaskName(),
+                                                null) : null;
+
+                                        if (res != null) {
+                                            old = res.get1();
+                                            readVer = res.get2();
+                                        }
+                                    }
+                                    else {
+                                        old = entry.innerGet(this,
+                                            /*swap*/false,
+                                            /*read-through*/false,
+                                            /*fail-fast*/false,
+                                            /*unmarshal*/retval,
+                                            /*metrics*/retval,
+                                            /*events*/retval,
+                                            /*temporary*/false,
+                                            CU.subjectId(this, cctx),
+                                            entryProcessor,
+                                            resolveTaskName(),
+                                            null);
+                                    }
                                 }
                                 catch (ClusterTopologyCheckedException e) {
                                     entry.context().evicts().touch(entry, topologyVersion());
 
                                     throw e;
                                 }
-                                catch (GridCacheFilterFailedException e) {
-                                    e.printStackTrace();
-
-                                    assert false : "Empty filter failed: " + e;
-                                }
                             }
                             else
                                 old = retval ? entry.rawGetOrUnmarshal(false) : entry.rawGet();
 
-                            if (!filter(entry, filter)) {
+                            if (old != null && hasFilters && !filter(entry.context(), cacheKey, old, filter)) {
                                 skipped = skip(skipped, cacheKey);
 
                                 ret.set(cacheCtx, old, false);
 
-                                if (!readCommitted() && old != null) {
+                                if (!readCommitted()) {
                                     // Enlist failed filters as reads for non-read-committed mode,
                                     // so future ops will get the same values.
                                     txEntry = addEntry(READ,
@@ -2272,9 +2205,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                         skipStore);
 
                                     txEntry.markValid();
+
+                                    if (needReadVer) {
+                                        assert readVer != null;
+
+                                        txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
+                                    }
                                 }
 
-                                if (readCommitted() || old == null)
+                                if (readCommitted())
                                     cacheCtx.evicts().touch(entry, topologyVersion());
 
                                 break; // While.
@@ -2305,9 +2244,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                 txEntry.markValid();
 
                                 if (old == null) {
-                                    boolean load = retval && !readThrough;
-
-                                    if (load) {
+                                    if (needVal) {
                                         if (missedForLoad == null)
                                             missedForLoad = new HashSet<>();
 
@@ -2324,6 +2261,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                                     }
                                 }
                                 else {
+                                    if (needReadVer) {
+                                        assert readVer != null;
+
+                                        txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
+                                    }
+
                                     if (retval && !transform)
                                         ret.set(cacheCtx, old, true);
                                     else {
@@ -2369,7 +2312,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                 else {
                     if (entryProcessor == null && txEntry.op() == TRANSFORM)
                         throw new IgniteCheckedException("Failed to enlist write value for key (cannot have update value in " +
-                            "transaction after transform closure is applied): " + key);
+                            "transaction after EntryProcessor is applied): " + key);
 
                     GridCacheEntryEx entry = txEntry.cached();
 
@@ -2378,7 +2321,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                     boolean del = txEntry.op() == DELETE && rmv;
 
                     if (!del) {
-                        if (!filter(entry, filter)) {
+                        if (hasFilters && !filter(entry.context(), cacheKey, v, filter)) {
                             skipped = skip(skipped, cacheKey);
 
                             ret.set(cacheCtx, v, false);
@@ -2439,15 +2382,19 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
         }
 
         if (missedForLoad != null) {
-            IgniteInternalFuture<Boolean> fut = loadMissing(
+            final boolean skipVals = singleRmv;
+
+            IgniteInternalFuture<Void> fut = loadMissing(
                 cacheCtx,
                 /*read through*/cacheCtx.config().isLoadPreviousValue() && !skipStore,
                 /*async*/true,
                 missedForLoad,
-                deserializePortables(cacheCtx),
-                /*skip values*/false,
-                new CI2<KeyCacheObject, Object>() {
-                    @Override public void apply(KeyCacheObject key, Object val) {
+                skipVals,
+                needReadVer,
+                new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
+                    @Override public void apply(KeyCacheObject key,
+                        @Nullable Object val,
+                        @Nullable GridCacheVersion loadVer) {
                         if (log.isDebugEnabled())
                             log.debug("Loaded value from remote node [key=" + key + ", val=" + val + ']');
 
@@ -2455,33 +2402,50 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
 
                         assert e != null;
 
-                        CacheObject cacheVal = cacheCtx.toCacheObject(val);
+                        if (needReadVer) {
+                            assert loadVer != null;
 
-                        if (e.op() == TRANSFORM) {
-                            GridCacheVersion ver;
+                            e.serializableReadVersion(singleRmv && val != null ? SER_READ_NOT_EMPTY_VER : loadVer);
+                        }
 
-                            try {
-                                ver = e.cached().version();
-                            }
-                            catch (GridCacheEntryRemovedException ex) {
-                                assert optimistic() : e;
+                        if (singleRmv) {
+                            assert !hasFilters && !retval;
+                            assert val == null || Boolean.TRUE.equals(val) : val;
 
-                                if (log.isDebugEnabled())
-                                    log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
+                            ret.set(cacheCtx, null, val != null);
+                        }
+                        else {
+                            CacheObject cacheVal = cacheCtx.toCacheObject(val);
 
-                                ver = null;
+                            if (e.op() == TRANSFORM) {
+                                GridCacheVersion ver;
+
+                                try {
+                                    ver = e.cached().version();
+                                }
+                                catch (GridCacheEntryRemovedException ex) {
+                                    assert optimistic() : e;
+
+                                    if (log.isDebugEnabled())
+                                        log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
+
+                                    ver = null;
+                                }
+
+                                addInvokeResult(e, cacheVal, ret, ver);
                             }
+                            else {
+                                boolean success = !hasFilters || isAll(e.context(), key, cacheVal, filter);
 
-                            addInvokeResult(e, cacheVal, ret, ver);
+                                ret.set(cacheCtx, cacheVal, success);
+                            }
                         }
-                        else
-                            ret.set(cacheCtx, cacheVal, true);
                     }
                 });
 
             return new GridEmbeddedFuture<>(
-                new C2<Boolean, Exception, Set<KeyCacheObject>>() {
-                    @Override public Set<KeyCacheObject> apply(Boolean b, Exception e) {
+                new C2<Void, Exception, Set<KeyCacheObject>>() {
+                    @Override public Set<KeyCacheObject> apply(Void b, Exception e) {
                         if (e != null)
                             throw new GridClosureException(e);
 
@@ -2495,6 +2459,31 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     }
 
     /**
+     * @param cctx Cache context.
+     * @param key Key.
+     * @param val Value.
+     * @param filter Filter.
+     * @return {@code True} if filter passed.
+     */
+    private boolean isAll(GridCacheContext cctx,
+        KeyCacheObject key,
+        CacheObject val,
+        CacheEntryPredicate[] filter) {
+        GridCacheEntryEx e = new GridDhtDetachedCacheEntry(cctx, key, 0, val, null, 0) {
+            @Nullable @Override public CacheObject peekVisibleValue() {
+                return rawGet();
+            }
+        };
+
+        for (CacheEntryPredicate p0 : filter) {
+            if (p0 != null && !p0.apply(e))
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
      * Post lock processing for put or remove.
      *
      * @param cacheCtx Context.
@@ -2555,29 +2544,22 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
 
                     if (retval || invoke) {
                         if (!cacheCtx.isNear()) {
-                            try {
-                                if (!hasPrevVal) {
-                                    boolean readThrough =
-                                        (invoke || cacheCtx.loadPreviousValue()) && !txEntry.skipStore();
-
-                                    v = cached.innerGet(this,
-                                        /*swap*/true,
-                                        readThrough,
-                                        /*failFast*/false,
-                                        /*unmarshal*/true,
-                                        /*metrics*/!invoke,
-                                        /*event*/!invoke && !dht(),
-                                        /*temporary*/false,
-                                        CU.subjectId(this, cctx),
-                                        null,
-                                        resolveTaskName(),
-                                        null);
-                                }
-                            }
-                            catch (GridCacheFilterFailedException e) {
-                                e.printStackTrace();
-
-                                assert false : "Empty filter failed: " + e;
+                            if (!hasPrevVal) {
+                                boolean readThrough =
+                                    (invoke || cacheCtx.loadPreviousValue()) && !txEntry.skipStore();
+
+                                v = cached.innerGet(this,
+                                    /*swap*/true,
+                                    readThrough,
+                                    /*failFast*/false,
+                                    /*unmarshal*/true,
+                                    /*metrics*/!invoke,
+                                    /*event*/!invoke && !dht(),
+                                    /*temporary*/false,
+                                    CU.subjectId(this, cctx),
+                                    null,
+                                    resolveTaskName(),
+                                    null);
                             }
                         }
                         else {
@@ -2725,7 +2707,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
      * @param invokeArgs Optional arguments for EntryProcessor.
      * @param drMap DR map.
      * @param retval Key-transform value map to store.
-     * @param cached Cached entry, if any.
      * @param filter Filter.
      * @return Operation future.
      */
@@ -2737,7 +2718,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
         @Nullable final Object[] invokeArgs,
         @Nullable final Map<KeyCacheObject, GridCacheDrInfo> drMap,
         final boolean retval,
-        @Nullable GridCacheEntryEx cached,
         @Nullable final CacheEntryPredicate[] filter
     ) {
         assert filter == null || invokeMap == null;
@@ -2778,8 +2758,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
             log.debug("Called putAllAsync(...) [tx=" + this + ", map=" + map0 + ", retval=" + retval + "]");
 
         assert map0 != null || invokeMap0 != null;
-        assert cached == null ||
-            (map0 != null && map0.size() == 1) || (invokeMap0 != null && invokeMap0.size() == 1);
 
         try {
             checkValid();
@@ -2814,7 +2792,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
             final IgniteInternalFuture<Set<KeyCacheObject>> loadFut = enlistWrite(
                 cacheCtx,
                 keySet,
-                cached,
                 opCtx != null ? opCtx.expiry() : null,
                 implicit,
                 map0,
@@ -2827,7 +2804,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                 enlisted,
                 drMap,
                 null,
-                opCtx != null && opCtx.skipStore());
+                opCtx != null && opCtx.skipStore(),
+                false);
 
             if (pessimistic()) {
                 // Loose all skipped.
@@ -2921,8 +2899,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                 }
                 else
                     return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Set<KeyCacheObject>>, GridCacheReturn>() {
-                        @Override
-                        public GridCacheReturn applyx(IgniteInternalFuture<Set<KeyCacheObject>> f) throws IgniteCheckedException {
+                        @Override public GridCacheReturn applyx(IgniteInternalFuture<Set<KeyCacheObject>> f) throws IgniteCheckedException {
                             f.get();
 
                             return ret;
@@ -2951,11 +2928,11 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
     @Override public <K, V> IgniteInternalFuture<GridCacheReturn> removeAllAsync(
         GridCacheContext cacheCtx,
         Collection<? extends K> keys,
-        @Nullable GridCacheEntryEx cached,
         boolean retval,
-        CacheEntryPredicate[] filter
+        CacheEntryPredicate[] filter,
+        boolean singleRmv
     ) {
-        return removeAllAsync0(cacheCtx, keys, null, cached, retval, filter);
+        return removeAllAsync0(cacheCtx, keys, null, retval, filter, singleRmv);
     }
 
     /**
@@ -2963,8 +2940,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
      * @param keys Keys to remove.
      * @param drMap DR map.
      * @param retval Flag indicating whether a value should be returned.
-     * @param cached Cached entry, if any. Will be provided only if size of keys collection is 1.
      * @param filter Filter.
+     * @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
      * @return Future for asynchronous remove.
      */
     @SuppressWarnings("unchecked")
@@ -2972,9 +2949,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
         final GridCacheContext cacheCtx,
         @Nullable final Collection<? extends K> keys,
         @Nullable Map<KeyCacheObject, GridCacheVersion> drMap,
-        @Nullable GridCacheEntryEx cached,
         final boolean retval,
-        @Nullable final CacheEntryPredicate[] filter) {
+        @Nullable final CacheEntryPredicate[] filter,
+        boolean singleRmv) {
         try {
             checkUpdatesAllowed(cacheCtx);
         }
@@ -2998,7 +2975,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
             keys0 = keys;
 
         assert keys0 != null;
-        assert cached == null || keys0.size() == 1;
 
         if (log.isDebugEnabled())
             log.debug("Called removeAllAsync(...) [tx=" + this + ", keys=" + keys0 + ", implicit=" + implicit +
@@ -3043,7 +3019,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
             final IgniteInternalFuture<Set<KeyCacheObject>> loadFut = enlistWrite(
                 cacheCtx,
                 keys0,
-                /** cached entry */null,
                 plc,
                 implicit,
                 /** lookup map */null,
@@ -3056,7 +3031,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
                 enlisted,
                 null,
                 drMap,
-                opCtx != null && opCtx.skipStore()
+                opCtx != null && opCtx.skipStore(),
+                singleRmv
             );
 
             if (log.isDebugEnabled())

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d7543a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
index 6f72290..0d83338 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
@@ -19,17 +19,17 @@ package org.apache.ignite.internal.processors.cache.transactions;
 
 import java.util.Collection;
 import java.util.Map;
+import javax.cache.Cache;
 import javax.cache.processor.EntryProcessor;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
 import org.apache.ignite.internal.processors.cache.GridCacheReturn;
 import org.apache.ignite.internal.processors.cache.KeyCacheObject;
 import org.apache.ignite.internal.processors.cache.dr.GridCacheDrInfo;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
-import org.apache.ignite.lang.IgniteBiInClosure;
+import org.apache.ignite.internal.util.lang.GridInClosure3;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -64,8 +64,6 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
     /**
      * @param cacheCtx Cache context.
      * @param keys Keys to get.
-     * @param cached Cached entry if this method is called from entry wrapper
-     *      Cached entry is passed if and only if there is only one key in collection of keys.
      * @param deserializePortable Deserialize portable flag.
      * @param skipVals Skip values flag.
      * @param keepCacheObjects Keep cache objects
@@ -75,7 +73,6 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
     public <K, V> IgniteInternalFuture<Map<K, V>> getAllAsync(
         GridCacheContext cacheCtx,
         Collection<KeyCacheObject> keys,
-        @Nullable GridCacheEntryEx cached,
         boolean deserializePortable,
         boolean skipVals,
         boolean keepCacheObjects,
@@ -85,17 +82,13 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
      * @param cacheCtx Cache context.
      * @param map Map to put.
      * @param retval Flag indicating whether a value should be returned.
-     * @param cached Cached entry, if any. Will be provided only if map has size 1.
      * @param filter Filter.
-     * @param ttl Time to live for entry. If negative, leave unchanged.
      * @return Future for put operation.
      */
     public <K, V> IgniteInternalFuture<GridCacheReturn> putAllAsync(
         GridCacheContext cacheCtx,
         Map<? extends K, ? extends V> map,
         boolean retval,
-        @Nullable GridCacheEntryEx cached,
-        long ttl,
         CacheEntryPredicate[] filter);
 
     /**
@@ -113,16 +106,16 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
      * @param cacheCtx Cache context.
      * @param keys Keys to remove.
      * @param retval Flag indicating whether a value should be returned.
-     * @param cached Cached entry, if any. Will be provided only if size of keys collection is 1.
      * @param filter Filter.
+     * @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
      * @return Future for asynchronous remove.
      */
     public <K, V> IgniteInternalFuture<GridCacheReturn> removeAllAsync(
         GridCacheContext cacheCtx,
         Collection<? extends K> keys,
-        @Nullable GridCacheEntryEx cached,
         boolean retval,
-        CacheEntryPredicate[] filter);
+        CacheEntryPredicate[] filter,
+        boolean singleRmv);
 
     /**
      * @param cacheCtx Cache context.
@@ -161,17 +154,17 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
      * @param readThrough Read through flag.
      * @param async if {@code True}, then loading will happen in a separate thread.
      * @param keys Keys.
-     * @param c Closure.
-     * @param deserializePortable Deserialize portable flag.
      * @param skipVals Skip values flag.
+     * @param needVer If {@code true} version is required for loaded values.
+     * @param c Closure to be applied for loaded values.
      * @return Future with {@code True} value if loading took place.
      */
-    public IgniteInternalFuture<Boolean> loadMissing(
+    public IgniteInternalFuture<Void> loadMissing(
         GridCacheContext cacheCtx,
         boolean readThrough,
         boolean async,
         Collection<KeyCacheObject> keys,
-        boolean deserializePortable,
         boolean skipVals,
-        IgniteBiInClosure<KeyCacheObject, Object> c);
+        boolean needVer,
+        GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c);
 }
\ No newline at end of file