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

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

Repository: ignite
Updated Branches:
  refs/heads/ignite-1.4-slow-server-debug 10956be4e -> aa3de3864


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-1.4-slow-server-debug
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
+}


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

Posted by yz...@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());
+        }
+    }
+}


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

Posted by yz...@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-1.4-slow-server-debug
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>


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

Posted by yz...@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);


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

Posted by yz...@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-1.4-slow-server-debug
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(-)
----------------------------------------------------------------------



[21/23] ignite git commit: Fixed test.

Posted by yz...@apache.org.
Fixed test.


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

Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 215b0cd9cac7d67fb5609058f8270e6bc38c8f76
Parents: 2a7d886
Author: sboikov <sb...@gridgain.com>
Authored: Wed Oct 28 17:25:10 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Oct 28 17:25:10 2015 +0300

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


http://git-wip-us.apache.org/repos/asf/ignite/blob/215b0cd9/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
index 70ddfa0..8c135ad 100644
--- 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
@@ -177,6 +177,8 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
             try {
                 IgniteCache<Integer, Integer> cache = ignite0.createCache(ccfg);
 
+                awaitPartitionMapExchange();
+
                 List<Integer> keys = testKeys(cache);
 
                 for (Integer key : keys)


[23/23] ignite git commit: Merge branches 'ignite-1.4-slow-server-debug' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-1.4-slow-server-debug

Posted by yz...@apache.org.
Merge branches 'ignite-1.4-slow-server-debug' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-1.4-slow-server-debug

Conflicts:
	modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
	modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
	modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java


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

Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: aa3de38649977745063ffbf153edb6ffca8c8706
Parents: 502223a
Author: Yakov Zhdanov <yz...@gridgain.com>
Authored: Wed Oct 28 18:22:05 2015 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Wed Oct 28 18:22:05 2015 +0300

----------------------------------------------------------------------
 .../internal/processors/cache/transactions/IgniteTxManager.java   | 3 ---
 1 file changed, 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/aa3de386/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 05129bb..e42dc4d 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
@@ -28,7 +28,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentNavigableMap;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteClientDisconnectedException;
@@ -62,7 +61,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.lang.IgnitePair;
 import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.F;
@@ -77,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 org.jsr166.ConcurrentLinkedHashMap;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_MAX_COMPLETED_TX_COUNT;


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

Posted by yz...@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/23] ignite git commit: testUseDefaultSuid fixed

Posted by yz...@apache.org.
testUseDefaultSuid fixed


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

Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: c39b6d43d61c9aab3dcd3240537a487c2e4605ad
Parents: 7f0b3fc
Author: agura <ag...@gridgain.com>
Authored: Wed Oct 28 15:57:10 2015 +0300
Committer: agura <ag...@gridgain.com>
Committed: Wed Oct 28 15:57:10 2015 +0300

----------------------------------------------------------------------
 .../apache/ignite/internal/IgniteKernal.java    | 69 ++++++++++----------
 .../GridDiscoveryManagerAttributesSelfTest.java | 23 ++++---
 2 files changed, 50 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c39b6d43/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 0865119..4820a93 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
@@ -17,6 +17,38 @@
 
 package org.apache.ignite.internal;
 
+import java.io.Externalizable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.management.JMException;
+import javax.management.ObjectName;
 import org.apache.ignite.IgniteAtomicLong;
 import org.apache.ignite.IgniteAtomicReference;
 import org.apache.ignite.IgniteAtomicSequence;
@@ -135,42 +167,10 @@ import org.apache.ignite.spi.IgniteSpi;
 import org.apache.ignite.spi.IgniteSpiVersionCheckException;
 import org.jetbrains.annotations.Nullable;
 
-import javax.management.JMException;
-import javax.management.ObjectName;
-import java.io.Externalizable;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InvalidObjectException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.text.DateFormat;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Timer;
-import java.util.UUID;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_CONFIG_URL;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_DAEMON;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_NO_ASCII;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_STARVATION_CHECK_INTERVAL;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_SUCCESS_FILE;
@@ -1268,7 +1268,8 @@ 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_MARSHALLER_USE_DFLT_SUID,
+            getBoolean(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_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/c39b6d43/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 6e2c635..3a2f3ba 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
@@ -25,9 +25,9 @@ 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.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
 import static org.apache.ignite.configuration.DeploymentMode.CONTINUOUS;
 import static org.apache.ignite.configuration.DeploymentMode.SHARED;
 
@@ -121,22 +121,29 @@ 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);
+        try {
+            doTestUseDefaultSuid(Boolean.TRUE.toString(), Boolean.FALSE.toString(), true);
+            doTestUseDefaultSuid(Boolean.FALSE.toString(), Boolean.TRUE.toString(), true);
+
+            doTestUseDefaultSuid(Boolean.TRUE.toString(), Boolean.TRUE.toString(), false);
+            doTestUseDefaultSuid(Boolean.FALSE.toString(), Boolean.FALSE.toString(), false);
+        }
+        finally {
+            System.setProperty(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID,
+                String.valueOf(OptimizedMarshaller.USE_DFLT_SUID));
+        }
     }
 
     /**
      * @throws Exception If failed.
      */
-    private void doTestUseDefaultSuid(Boolean first, Boolean second, boolean fail) throws Exception {
+    private void doTestUseDefaultSuid(String first, String second, boolean fail) throws Exception {
         try {
-            GridTestUtils.setFieldValue(null, OptimizedMarshaller.class, "USE_DFLT_SUID", first);
+            System.setProperty(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID, first);
 
             startGrid(0);
 
-            GridTestUtils.setFieldValue(null, OptimizedMarshaller.class, "USE_DFLT_SUID", second);
+            System.setProperty(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID, second);
 
             try {
                 startGrid(1);


[02/23] ignite git commit: review

Posted by yz...@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-1.4-slow-server-debug
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({


[20/23] ignite git commit: Merge remote-tracking branch 'origin/master'

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


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

Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 2a7d886553a967b330342d7b6734a256ce890946
Parents: a5d50a6 c39b6d4
Author: Anton Vinogradov <av...@apache.org>
Authored: Wed Oct 28 17:11:30 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Oct 28 17:11:30 2015 +0300

----------------------------------------------------------------------
 .../ClientAbstractMultiThreadedSelfTest.java    |    3 +-
 .../apache/ignite/IgniteSystemProperties.java   |    9 +
 .../affinity/fair/FairAffinityFunction.java     |  497 +-
 .../rendezvous/RendezvousAffinityFunction.java  |  140 +-
 .../configuration/TransactionConfiguration.java |    6 +-
 .../apache/ignite/internal/IgniteKernal.java    |   69 +-
 .../ignite/internal/IgniteNodeAttributes.java   |    3 +
 .../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    |   26 -
 .../processors/cache/GridCacheUtils.java        |   50 +
 .../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 -
 .../continuous/CacheContinuousQueryManager.java |    6 +-
 .../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 +-
 .../ignite/internal/util/lang/GridFunc.java     |    8 +-
 .../optimized/OptimizedMarshaller.java          |   10 +-
 .../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  |   99 +
 ...airAffinityFunctionBackupFilterSelfTest.java |   35 +
 ...ffinityFunctionExcludeNeighborsSelfTest.java |   31 +
 .../fair/FairAffinityFunctionNodesSelfTest.java |  245 +
 .../fair/FairAffinityFunctionSelfTest.java      |   31 +
 .../GridFairAffinityFunctionNodesSelfTest.java  |  245 -
 .../fair/GridFairAffinityFunctionSelfTest.java  |  270 --
 .../IgniteFairAffinityDynamicCacheSelfTest.java |   99 -
 ...ousAffinityFunctionBackupFilterSelfTest.java |   35 +
 ...ffinityFunctionExcludeNeighborsSelfTest.java |   32 +
 .../RendezvousAffinityFunctionSelfTest.java     |   50 +
 .../GridDiscoveryManagerAttributesSelfTest.java |   51 +-
 .../cache/CacheNearReaderUpdateTest.java        |  388 ++
 .../CacheSerializableTransactionsTest.java      | 4295 ++++++++++++++++++
 .../cache/CrossCacheTxRandomOperationsTest.java |    8 +-
 .../GridCacheAbstractFailoverSelfTest.java      |   14 +-
 .../cache/GridCacheAbstractFullApiSelfTest.java |    4 +-
 .../GridCacheAbstractLocalStoreSelfTest.java    |    5 +
 .../GridCacheAbstractRemoveFailureTest.java     |   94 +-
 .../GridCacheConcurrentTxMultiNodeTest.java     |    3 -
 ...idCacheConfigurationConsistencySelfTest.java |   17 -
 .../cache/GridCacheMvccFlagsTest.java           |    6 +-
 .../cache/GridCacheMvccPartitionedSelfTest.java |  164 +
 .../processors/cache/GridCacheMvccSelfTest.java |    3 +-
 .../processors/cache/GridCacheTestEntryEx.java  |   53 +-
 .../cache/IgniteCacheCreateRestartSelfTest.java |    2 +
 .../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 +-
 .../inmemory/GridTestSwapSpaceSpi.java          |    8 +
 .../ignite/testframework/GridTestUtils.java     |   19 +-
 .../junits/common/GridCommonAbstractTest.java   |   19 +-
 .../IgniteCacheFullApiSelfTestSuite.java        |    8 +
 .../ignite/testsuites/IgniteCacheTestSuite.java |   20 +-
 .../testsuites/IgniteCacheTestSuite2.java       |   14 +-
 .../testsuites/IgniteCacheTestSuite5.java       |   40 +
 .../cache/IgniteCacheAbstractQuerySelfTest.java |    4 +
 modules/jms11/pom.xml                           |    9 +-
 .../stream/jms11/IgniteJmsStreamerTest.java     |    9 +-
 .../apache/ignite/stream/mqtt/MqttStreamer.java |  386 +-
 .../stream/mqtt/IgniteMqttStreamerTest.java     |  142 +-
 .../mqtt/IgniteMqttStreamerTestSuite.java       |    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 +
 132 files changed, 11827 insertions(+), 3907 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2a7d8865/modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java
----------------------------------------------------------------------
diff --cc modules/core/src/test/java/org/apache/ignite/cache/affinity/fair/FairAffinityDynamicCacheSelfTest.java
index 0000000,0b32320..ef67495
mode 000000,100644..100644
--- 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
@@@ -1,0 -1,97 +1,99 @@@
+ /*
+  * 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 {
++        fail("https://issues.apache.org/jira/browse/IGNITE-647");
++
+         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);
+     }
+ }


[19/23] ignite git commit: Muted test

Posted by yz...@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/a5d50a60
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a5d50a60
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a5d50a60

Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: a5d50a60025559435673a066d61799d1aafe3b29
Parents: df931bd
Author: Anton Vinogradov <av...@apache.org>
Authored: Wed Oct 28 17:10:55 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Oct 28 17:10:55 2015 +0300

----------------------------------------------------------------------
 .../affinity/fair/IgniteFairAffinityDynamicCacheSelfTest.java      | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a5d50a60/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
index eb1c455..f95265d 100644
--- 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
@@ -71,6 +71,8 @@ public class IgniteFairAffinityDynamicCacheSelfTest extends GridCommonAbstractTe
      * @throws Exception If failed.
      */
     public void testStartStopCache() throws Exception {
+        fail("https://issues.apache.org/jira/browse/IGNITE-647");
+
         CacheConfiguration<Integer, Integer> cacheCfg = new CacheConfiguration<>();
 
         cacheCfg.setCacheMode(CacheMode.PARTITIONED);


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

Posted by yz...@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);
+                }
+            };
+        }
+    }
+}


[17/23] ignite git commit: Ignite JMS 1.1 Streamer tests: Remove dependency on KahaDB & persistence.

Posted by yz...@apache.org.
Ignite JMS 1.1 Streamer tests: Remove dependency on KahaDB & persistence.


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

Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 7f0b3fce5ae6ed0652f3dbf64f0482e63d36c38d
Parents: e769c3a
Author: Raul Kripalani <ra...@apache.org>
Authored: Wed Oct 28 12:37:38 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Wed Oct 28 12:37:38 2015 +0000

----------------------------------------------------------------------
 modules/jms11/pom.xml                                       | 7 -------
 .../apache/ignite/stream/jms11/IgniteJmsStreamerTest.java   | 9 +++++++--
 2 files changed, 7 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/7f0b3fce/modules/jms11/pom.xml
----------------------------------------------------------------------
diff --git a/modules/jms11/pom.xml b/modules/jms11/pom.xml
index 72a643b..3c37e7f 100644
--- a/modules/jms11/pom.xml
+++ b/modules/jms11/pom.xml
@@ -66,13 +66,6 @@
         </dependency>
 
         <dependency>
-            <groupId>org.apache.activemq</groupId>
-            <artifactId>activemq-kahadb-store</artifactId>
-            <version>${activemq.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-log4j</artifactId>
             <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/ignite/blob/7f0b3fce/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java b/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java
index 0e110a5..238d939 100644
--- a/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java
+++ b/modules/jms11/src/test/java/org/apache/ignite/stream/jms11/IgniteJmsStreamerTest.java
@@ -83,14 +83,19 @@ public class IgniteJmsStreamerTest extends GridCommonAbstractTest {
         grid().<Integer, String>getOrCreateCache(defaultCacheConfiguration());
 
         broker = new BrokerService();
-        broker.deleteAllMessages();
+        broker.setDeleteAllMessagesOnStartup(true);
         broker.setPersistent(false);
+        broker.setPersistenceAdapter(null);
+        broker.setPersistenceFactory(null);
 
         PolicyMap policyMap = new PolicyMap();
         PolicyEntry policy = new PolicyEntry();
+
         policy.setQueuePrefetch(1);
+
         broker.setDestinationPolicy(policyMap);
         broker.getDestinationPolicy().setDefaultEntry(policy);
+        broker.setSchedulerSupport(false);
 
         broker.start(true);
 
@@ -102,8 +107,8 @@ public class IgniteJmsStreamerTest extends GridCommonAbstractTest {
     public void afterTest() throws Exception {
         grid().cache(null).clear();
 
-        broker.deleteAllMessages();
         broker.stop();
+        broker.deleteAllMessages();
     }
 
     public void testQueueFromName() throws Exception {


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

Posted by yz...@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


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

Posted by yz...@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>

[22/23] ignite git commit: Merge branches 'ignite-1.4-slow-server-debug' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-1.4-slow-server-debug

Posted by yz...@apache.org.
Merge branches 'ignite-1.4-slow-server-debug' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-1.4-slow-server-debug

Conflicts:
	modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
	modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
	modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java


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

Branch: refs/heads/ignite-1.4-slow-server-debug
Commit: 502223a8a5e9d88b90f402298013b503817181e7
Parents: 10956be 215b0cd
Author: Yakov Zhdanov <yz...@gridgain.com>
Authored: Wed Oct 28 18:21:51 2015 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Wed Oct 28 18:21:51 2015 +0300

----------------------------------------------------------------------
 .../configuration/TransactionConfiguration.java |    6 +-
 .../apache/ignite/internal/IgniteKernal.java    |   69 +-
 .../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         |   59 +-
 .../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            |   16 +-
 .../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     |  325 +-
 .../cache/version/GridCacheVersionManager.java  |   73 +-
 .../datastreamer/DataStreamerImpl.java          |    2 +-
 .../apache/ignite/transactions/Transaction.java |    2 +-
 .../transactions/TransactionIsolation.java      |    3 +-
 .../fair/FairAffinityDynamicCacheSelfTest.java  |    2 +
 .../GridDiscoveryManagerAttributesSelfTest.java |   23 +-
 .../cache/CacheNearReaderUpdateTest.java        |  388 ++
 .../CacheSerializableTransactionsTest.java      | 4297 ++++++++++++++++++
 .../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 +
 modules/jms11/pom.xml                           |    9 +-
 .../stream/jms11/IgniteJmsStreamerTest.java     |    9 +-
 .../apache/ignite/stream/mqtt/MqttStreamer.java |  386 +-
 .../stream/mqtt/IgniteMqttStreamerTest.java     |  142 +-
 .../mqtt/IgniteMqttStreamerTestSuite.java       |    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 +
 91 files changed, 9644 insertions(+), 2475 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
index e164be0,fcbf58d..93303c8
--- 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
@@@ -577,17 -579,37 +579,37 @@@ public class GridDistributedTxRemoteAda
                                      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, 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),
++                                                near() ? null : explicitVer,
++                                                CU.subjectId(this, cctx),
+                                                 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) {
@@@ -603,10 -625,20 +625,19 @@@
                                          }
                                      }
                                      else if (op == DELETE) {
-                                         cached.innerRemove(this, eventNodeId(), nodeId,
-                                             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/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index 48fa133,d806801..612e2bb
--- 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
@@@ -59,7 -56,9 +58,8 @@@ import org.apache.ignite.internal.proce
  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;
  import org.apache.ignite.internal.util.future.GridCompoundFuture;
  import org.apache.ignite.internal.util.future.GridFutureAdapter;

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index fd1453b,af43113..0002180
--- 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
@@@ -17,11 -17,8 +17,10 @@@
  
  package org.apache.ignite.internal.processors.cache.distributed.near;
  
 +import java.util.ArrayDeque;
  import java.util.Collection;
- import java.util.Collections;
  import java.util.List;
 +import java.util.Queue;
  import java.util.UUID;
  import java.util.concurrent.atomic.AtomicBoolean;
  import org.apache.ignite.IgniteCheckedException;
@@@ -59,9 -53,9 +55,8 @@@ import org.apache.ignite.internal.util.
  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;
  
  import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRANSFORM;
  import static org.apache.ignite.transactions.TransactionState.PREPARED;
@@@ -483,9 -293,9 +294,9 @@@ public class GridNearOptimisticTxPrepar
  
          txMapping = new GridDhtTxMapping();
  
 -        ConcurrentLinkedDeque8<GridDistributedTxMapping> mappings = new ConcurrentLinkedDeque8<>();
 +        Queue<GridDistributedTxMapping> mappings = new ArrayDeque<>();
  
-         if (!F.isEmpty(reads) || !F.isEmpty(writes)) {
+         if (!F.isEmpty(writes)) {
              for (int cacheId : tx.activeCacheIds()) {
                  GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
  

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
index c7cc3ae,46c9f3e..a9dbda2
--- 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
@@@ -246,59 -265,44 +246,61 @@@ public final class GridNearTxFinishFutu
                  }
              }
  
 +            if (initialized() || err != null) {
 +                if (tx.needCheckBackup()) {
 +                    assert tx.onePhaseCommit();
 +
 +                    if (err != null)
 +                        err = new TransactionRollbackException("Failed to commit transaction.", err);
 +
 +                    try {
 +                        tx.finish(err == null);
 +                    }
 +                    catch (IgniteCheckedException e) {
 +                        if (err != null)
 +                            err.addSuppressed(e);
 +                        else
 +                            err = e;
 +                    }
 +                }
 +
-                 if (tx.onePhaseCommit()) {
-                     finishOnePhase();
+             if (tx.onePhaseCommit()) {
+                 boolean commit = this.commit && err == null;
  
-                     tx.tmFinish(commit && err == null);
-                 }
+                 finishOnePhase(commit);
+ 
+                 tx.tmFinish(commit);
+             }
  
 -            Throwable th = this.err.get();
 +                if (super.onDone(tx0, err)) {
 +                    if (error() instanceof IgniteTxHeuristicCheckedException) {
 +                        AffinityTopologyVersion topVer = tx.topologyVersion();
  
 -            if (super.onDone(tx0, th != null ? th : err)) {
 -                if (error() instanceof IgniteTxHeuristicCheckedException) {
 -                    AffinityTopologyVersion topVer = tx.topologyVersion();
 +                        for (IgniteTxEntry e : tx.writeMap().values()) {
 +                            GridCacheContext cacheCtx = e.context();
  
 -                    for (IgniteTxEntry e : tx.writeMap().values()) {
 -                        GridCacheContext cacheCtx = e.context();
 -
 -                        try {
 -                            if (e.op() != NOOP && !cacheCtx.affinity().localNode(e.key(), topVer)) {
 -                                GridCacheEntryEx entry = cacheCtx.cache().peekEx(e.key());
 +                            try {
 +                                if (e.op() != NOOP && !cacheCtx.affinity().localNode(e.key(), topVer)) {
 +                                    GridCacheEntryEx entry = cacheCtx.cache().peekEx(e.key());
  
 -                                if (entry != null)
 -                                    entry.invalidate(null, tx.xidVersion());
 +                                    if (entry != null)
 +                                        entry.invalidate(null, tx.xidVersion());
 +                                }
                              }
 -                        }
 -                        catch (Throwable t) {
 -                            U.error(log, "Failed to invalidate entry.", t);
 +                            catch (Throwable t) {
 +                                U.error(log, "Failed to invalidate entry.", t);
  
 -                            if (t instanceof Error)
 -                                throw (Error)t;
 +                                if (t instanceof Error)
 +                                    throw (Error)t;
 +                            }
                          }
                      }
 -                }
  
 -                // Don't forget to clean up.
 -                cctx.mvcc().removeFuture(this);
 +                    // Don't forget to clean up.
 +                    cctx.mvcc().removeFuture(this);
  
 -                return true;
 +                    return true;
 +                }
              }
          }
  
@@@ -508,16 -512,9 +510,16 @@@
      }
  
      /**
-      *
+      * @param commit Commit flag.
       */
-     private void finishOnePhase() {
+     private void finishOnePhase(boolean commit) {
 +        assert Thread.holdsLock(this);
 +
 +        if (finishOnePhaseCalled)
 +            return;
 +
 +        finishOnePhaseCalled = true;
 +
          // 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()) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index d97e648,c1e9202..05129bb
--- 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
@@@ -24,8 -23,8 +24,7 @@@ import java.util.Collections
  import java.util.HashSet;
  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;
@@@ -134,29 -127,9 +132,19 @@@ public class IgniteTxManager extends Gr
      /** 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));
 +    private final GridBoundedConcurrentOrderedMap<GridCacheVersion, Boolean> completedVersSorted =
 +        new GridBoundedConcurrentOrderedMap<>(
 +            Integer.getInteger(IGNITE_MAX_COMPLETED_TX_COUNT, DFLT_MAX_COMPLETED_TX_CNT));
 +
 +    /** Committed local transactions. */
 +    private final ConcurrentLinkedHashMap<GridCacheVersion, Boolean> completedVersHashMap =
 +        new ConcurrentLinkedHashMap<>(
 +            Integer.getInteger(IGNITE_MAX_COMPLETED_TX_COUNT, DFLT_MAX_COMPLETED_TX_CNT),
 +            0.75f,
 +            Runtime.getRuntime().availableProcessors() * 2,
 +            Integer.getInteger(IGNITE_MAX_COMPLETED_TX_COUNT, DFLT_MAX_COMPLETED_TX_CNT),
 +            PER_SEGMENT_Q);
  
      /** Transaction finish synchronizer. */
      private GridCacheTxFinishSync txFinishSync;
@@@ -324,40 -297,8 +312,9 @@@
          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());
 +        X.println(">>>   completedVersSortedSize: " + completedVersSorted.size());
 +        X.println(">>>   completedVersHashMapSize: " + completedVersHashMap.sizex());
      }
  
      /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractFullApiSelfTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheTestEntryEx.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/502223a8/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
----------------------------------------------------------------------


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

Posted by yz...@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-1.4-slow-server-debug
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


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

Posted by yz...@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;
+    }
+}


[05/23] ignite git commit: Merge branch 'master' into ignite-1747

Posted by yz...@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-1.4-slow-server-debug
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(-)
----------------------------------------------------------------------



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

Posted by yz...@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-1.4-slow-server-debug
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(-)
----------------------------------------------------------------------



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

Posted by yz...@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-1.4-slow-server-debug
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())
             );


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

Posted by yz...@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,