ignite-6445 Deadlock detection triggering fixed

Signed-off-by: Andrey Gura <[email protected]>


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

Branch: refs/heads/ignite-2.3
Commit: 78688431e6fb183235e310f6830c9b499d0f7d5e
Parents: 405749a
Author: Vitaliy Biryukov <[email protected]>
Authored: Thu Sep 28 16:27:52 2017 +0300
Committer: Andrey Gura <[email protected]>
Committed: Thu Sep 28 16:27:52 2017 +0300

----------------------------------------------------------------------
 .../distributed/dht/GridDhtTxPrepareFuture.java |  4 +-
 .../TxOptimisticDeadlockDetectionTest.java      | 78 +++++++++++++++++---
 2 files changed, 69 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/78688431/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 00ce1d5..6873890 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
@@ -973,7 +973,7 @@ public final class GridDhtTxPrepareFuture extends 
GridCacheCompoundFuture<Ignite
         if (last || tx.isSystemInvalidate())
             tx.state(PREPARED);
 
-        if (super.onDone(res, err)) {
+        if (super.onDone(res, res == null ? err : null)) {
             // Don't forget to clean up.
             cctx.mvcc().removeVersionedFuture(this);
 
@@ -992,7 +992,7 @@ public final class GridDhtTxPrepareFuture extends 
GridCacheCompoundFuture<Ignite
     public void complete() {
         GridNearTxPrepareResponse res = new GridNearTxPrepareResponse();
 
-        res.error(new IgniteCheckedException("Failed to prepare 
transaction."));
+        res.error(err != null ? err : new IgniteCheckedException("Failed to 
prepare transaction."));
 
         onComplete(res);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/78688431/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxOptimisticDeadlockDetectionTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxOptimisticDeadlockDetectionTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxOptimisticDeadlockDetectionTest.java
index 3414227..91a5742 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxOptimisticDeadlockDetectionTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/transactions/TxOptimisticDeadlockDetectionTest.java
@@ -19,7 +19,7 @@ package 
org.apache.ignite.internal.processors.cache.transactions;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -45,6 +45,7 @@ import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPr
 import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.util.GridConcurrentHashSet;
+import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteInClosure;
 import org.apache.ignite.plugin.extensions.communication.Message;
@@ -165,6 +166,16 @@ public class TxOptimisticDeadlockDetectionTest extends 
AbstractDeadlockDetection
     }
 
     /**
+     * @throws Exception If failed.
+     */
+    public void testDeadlocksPartitionedNearTxOnPrimary() throws Exception {
+        for (CacheWriteSynchronizationMode syncMode : 
CacheWriteSynchronizationMode.values()) {
+            doTestDeadlocksTxOnPrimary(createCache(PARTITIONED, syncMode, 
true),  ORDINAL_START_KEY);
+            doTestDeadlocksTxOnPrimary(createCache(PARTITIONED, syncMode, 
true),  CUSTOM_START_KEY);
+        }
+    }
+
+    /**
      * @param cacheMode Cache mode.
      * @param syncMode Write sync mode.
      * @param near Near.
@@ -224,16 +235,55 @@ public class TxOptimisticDeadlockDetectionTest extends 
AbstractDeadlockDetection
     }
 
     /**
+     * @param cache Cache.
+     * @param startKey Start key.
+     */
+    private void doTestDeadlocksTxOnPrimary(IgniteCache cache, Object 
startKey) {
+        try {
+            awaitPartitionMapExchange();
+
+            doTestDeadlock(3, false, false, startKey, true);
+
+            doTestDeadlock(4, false, false, startKey, true);
+        }
+        catch (Throwable e) {
+            U.error(log, "Unexpected exception: ", e);
+
+            //TODO "if" statement will be removed after fixing 
https://issues.apache.org/jira/browse/IGNITE-6445
+            if (!e.getMessage().equals("Failed to detect deadlock"))
+                fail();
+        }
+        finally {
+            if (cache != null)
+                cache.destroy();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void doTestDeadlock(
+        int txCnt,
+        boolean lockPrimaryFirst,
+        boolean clientTx,
+        Object startKey
+    ) throws Exception {
+        doTestDeadlock(txCnt, lockPrimaryFirst, clientTx, startKey, false);
+    }
+
+    /**
      * @throws Exception If failed.
      */
     private void doTestDeadlock(
         final int txCnt,
         boolean lockPrimaryFirst,
         final boolean clientTx,
-        Object startKey
+        Object startKey,
+        boolean txOnPrimary
     ) throws Exception {
+
         log.info(">>> Test deadlock [txCnt=" + txCnt + ", lockPrimaryFirst=" + 
lockPrimaryFirst +
-            ", clientTx=" + clientTx + ", startKey=" + startKey + ']');
+            ", clientTx=" + clientTx + ", startKey=" + startKey + ", 
txOnPrimary=" + txOnPrimary + ']');
 
         TestCommunicationSpi.init(txCnt);
 
@@ -241,7 +291,7 @@ public class TxOptimisticDeadlockDetectionTest extends 
AbstractDeadlockDetection
 
         final AtomicReference<TransactionDeadlockException> deadlockErr = new 
AtomicReference<>();
 
-        final List<List<Object>> keySets = generateKeys(txCnt, startKey, 
!lockPrimaryFirst);
+        final List<List<Object>> keySets = generateKeys(txCnt, startKey, 
!lockPrimaryFirst, txOnPrimary);
 
         final Set<Object> involvedKeys = new GridConcurrentHashSet<>();
         final Set<Object> involvedLockedKeys = new GridConcurrentHashSet<>();
@@ -283,14 +333,12 @@ public class TxOptimisticDeadlockDetectionTest extends 
AbstractDeadlockDetection
                         
((IgniteCacheProxy)cache).context().affinity().primaryByKey(key, NONE);
 
                     List<Object> primaryKeys = primaryKeys(
-                        grid(primaryNode).cache(CACHE_NAME), 5, 
incrementKey(key , (100 * threadNum)));
+                        grid(primaryNode).cache(CACHE_NAME), 5, 
incrementKey(key, (100 * threadNum)));
 
-                    Map<Object, Integer> entries = new HashMap<>();
+                    Map<Object, Integer> entries = new LinkedHashMap<>();
 
                     involvedKeys.add(key);
 
-                    entries.put(key, 0);
-
                     for (Object o : primaryKeys) {
                         involvedKeys.add(o);
 
@@ -303,6 +351,8 @@ public class TxOptimisticDeadlockDetectionTest extends 
AbstractDeadlockDetection
                         entries.put(k, 2);
                     }
 
+                    entries.put(key, 0);
+
                     log.info(">>> Performs put [node=" + 
((IgniteKernal)ignite).localNode().id() +
                         ", tx=" + tx.xid() + ", entries=" + entries + ']');
 
@@ -313,7 +363,12 @@ public class TxOptimisticDeadlockDetectionTest extends 
AbstractDeadlockDetection
                 catch (Throwable e) {
                     log.info("Expected exception: " + e);
 
-                    e.printStackTrace(System.out);
+                    String stackTrace = X.getFullStackTrace(e);
+
+                    log.info(stackTrace);
+
+                    assertTrue("DeadlockDetection hasn't executed at "+ 
(threadNum - 1) + " node.",
+                        
stackTrace.contains(TxDeadlockDetection.class.getName()));
 
                     // At least one stack trace should contain 
TransactionDeadlockException.
                     if (hasCause(e, TransactionTimeoutException.class) &&
@@ -364,13 +419,14 @@ public class TxOptimisticDeadlockDetectionTest extends 
AbstractDeadlockDetection
     /**
      * @param nodesCnt Nodes count.
      */
-    private <T> List<List<T>> generateKeys(int nodesCnt, T startKey, boolean 
reverse) throws IgniteCheckedException {
+    private <T> List<List<T>> generateKeys(int nodesCnt, T startKey, boolean 
reverse,
+        boolean txOnPrimary) throws IgniteCheckedException {
         List<List<T>> keySets = new ArrayList<>();
 
         for (int i = 0; i < nodesCnt; i++) {
             List<T> keys = new ArrayList<>(2);
 
-            int n1 = i + 1;
+            int n1 = txOnPrimary ? i : i + 1;
             int n2 = n1 + 1;
 
             int i1 = n1 < nodesCnt ? n1 : n1 - nodesCnt;

Reply via email to