Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
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.F;
import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
Expand All @@ -55,7 +56,7 @@
public static final int DFLT_TX_DEADLOCK_DETECTION_TIMEOUT = 60000;

/** Deadlock detection maximum iterations. */
private static int deadLockTimeout =
private static final int deadLockTimeout =

Check failure on line 59 in modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxDeadlockDetection.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this constant name to match the regular expression '^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$'.

See more on https://sonarcloud.io/project/issues?id=apache_ignite&issues=AZ4m0MUNehSBvneslj4Y&open=AZ4m0MUNehSBvneslj4Y&pullRequest=13136
getInteger(IGNITE_TX_DEADLOCK_DETECTION_TIMEOUT, DFLT_TX_DEADLOCK_DETECTION_TIMEOUT);

/** Sequence. */
Expand All @@ -80,7 +81,7 @@
*
* @param tx Target tx.
* @param keys Keys.
* @return {@link TxDeadlock} if found, otherwise - {@code null}.
* @return {@link TxDeadlockFuture} future.
*/
TxDeadlockFuture detectDeadlock(IgniteInternalTx tx, Set<IgniteTxKey> keys) {
GridCacheVersion txId = tx.nearXidVersion();
Expand All @@ -101,7 +102,7 @@
* @param wfg Wait-for-graph.
* @param txId Tx ID - start vertex for cycle search in graph.
*/
static List<GridCacheVersion> findCycle(Map<GridCacheVersion, Set<GridCacheVersion>> wfg, GridCacheVersion txId) {
static @Nullable List<GridCacheVersion> findCycle(Map<GridCacheVersion, Set<GridCacheVersion>> wfg, GridCacheVersion txId) {

Check failure on line 105 in modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxDeadlockDetection.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=apache_ignite&issues=AZ4m0MUNehSBvneslj4Z&open=AZ4m0MUNehSBvneslj4Z&pullRequest=13136
if (wfg == null || wfg.isEmpty())
return null;

Expand Down Expand Up @@ -181,7 +182,7 @@

/** Pending keys. */
@GridToStringInclude
private Map<UUID, Set<IgniteTxKey>> pendingKeys = new HashMap<>();
private final Map<UUID, Set<IgniteTxKey>> pendingKeys = new HashMap<>();

/** Nodes queue. */
@GridToStringInclude
Expand Down Expand Up @@ -322,7 +323,7 @@
* Maps tx keys on nodes. Key can be mapped on some node if this node is primary for given key or
* node is near for transaction that holds or requests lock for key.
*
* Key will not be be mapped to node if both key and node are already handled.
* Key will not be mapped to node if both key and node are already handled.
*
* @param txKeys Tx keys.
* @param txLocks Tx locks.
Expand All @@ -348,10 +349,7 @@
// Process this node earlier than other in order to optimize amount of requests.
preferredNodes.add(nodeId);

Set<IgniteTxKey> mappedKeys = pendingKeys.get(nodeId);

if (mappedKeys == null)
pendingKeys.put(nodeId, mappedKeys = new HashSet<>());
Set<IgniteTxKey> mappedKeys = pendingKeys.computeIfAbsent(nodeId, k -> new HashSet<>());

mappedKeys.add(txKey);
}
Expand All @@ -363,10 +361,7 @@
else
nodesQueue.addLast(nearNodeId);

Set<IgniteTxKey> mappedKeys = pendingKeys.get(nearNodeId);

if (mappedKeys == null)
pendingKeys.put(nearNodeId, mappedKeys = new HashSet<>());
Set<IgniteTxKey> mappedKeys = pendingKeys.computeIfAbsent(nearNodeId, k -> new HashSet<>());

mappedKeys.add(txKey);
}
Expand All @@ -387,10 +382,7 @@

nodesQueue.addLast(nodeId);

Set<IgniteTxKey> mappedKeys = pendingKeys.get(nodeId);

if (mappedKeys == null)
pendingKeys.put(nodeId, mappedKeys = new HashSet<>());
Set<IgniteTxKey> mappedKeys = pendingKeys.computeIfAbsent(nodeId, k -> new HashSet<>());

mappedKeys.add(txKey);
}
Expand All @@ -417,15 +409,15 @@
private void merge(TxLocksResponse res) {
Map<IgniteTxKey, List<TxLock>> txLocks = res.txLocks();

if (txLocks == null || txLocks.isEmpty())
if (F.isEmpty(txLocks))
return;

for (Map.Entry<IgniteTxKey, List<TxLock>> e : txLocks.entrySet()) {
IgniteTxKey txKey = e.getKey();

List<TxLock> lockList = e.getValue();

if (lockList != null && !lockList.isEmpty()) {
if (!F.isEmpty(lockList)) {
for (TxLock lock : lockList) {
if (lock.owner() || lock.candiate()) {
if (txs.get(lock.txId()) == null)
Expand All @@ -435,18 +427,12 @@
if (lock.owner()) {
GridCacheVersion txId = lock.txId();

Set<IgniteTxKey> keys = txLockedKeys.get(txId);

if (keys == null)
txLockedKeys.put(txId, keys = new HashSet<>());
Set<IgniteTxKey> keys = txLockedKeys.computeIfAbsent(txId, k -> new HashSet<>());

Check warning on line 430 in modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxDeadlockDetection.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename "keys" which hides the field declared at line 174.

See more on https://sonarcloud.io/project/issues?id=apache_ignite&issues=AZ4m0MUNehSBvneslj4a&open=AZ4m0MUNehSBvneslj4a&pullRequest=13136

keys.add(txKey);
}
else if (lock.candiate()) {
Set<GridCacheVersion> txs = txRequestedKeys.get(txKey);

if (txs == null)
txRequestedKeys.put(txKey, txs = new HashSet<>());
Set<GridCacheVersion> txs = txRequestedKeys.computeIfAbsent(txKey, k -> new HashSet<>());

Check warning on line 435 in modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TxDeadlockDetection.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename "txs" which hides the field declared at line 207.

See more on https://sonarcloud.io/project/issues?id=apache_ignite&issues=AZ4m0MUNehSBvneslj4b&open=AZ4m0MUNehSBvneslj4b&pullRequest=13136

txs.add(lock.txId());
}
Expand All @@ -473,10 +459,7 @@
txOwner = lock.txId();

if (keys.contains(e.getKey()) && !txId.equals(lock.txId())) {
Set<GridCacheVersion> waitingTxs = wfg.get(txId);

if (waitingTxs == null)
wfg.put(txId, waitingTxs = new HashSet<>());
Set<GridCacheVersion> waitingTxs = wfg.computeIfAbsent(txId, k -> new HashSet<>());

waitingTxs.add(lock.txId());
}
Expand All @@ -487,10 +470,7 @@
if (lock.candiate() || lock.owner()) {
GridCacheVersion txId0 = lock.txId();

Set<GridCacheVersion> waitForTxs = wfg.get(txId0);

if (waitForTxs == null)
wfg.put(txId0, waitForTxs = new HashSet<>());
Set<GridCacheVersion> waitForTxs = wfg.computeIfAbsent(txId0, k -> new HashSet<>());

waitForTxs.add(txOwner);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.DataRegionConfiguration;
Expand Down Expand Up @@ -165,6 +164,9 @@ private void checkCauseObject(
final TransactionIsolation isolation,
final boolean oneOp
) throws Exception {
if (nodes > 1)
awaitPartitionMapExchange();

final Ignite ignite = grid(new Random().nextInt(nodes));

final IgniteCache<Integer, Account> cache = ignite.cache(DEFAULT_CACHE_NAME);
Expand All @@ -183,7 +185,7 @@ private void checkCauseObject(
final CyclicBarrier barrier = new CyclicBarrier(2);

IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new CAX() {
@Override public void applyx() throws IgniteCheckedException {
@Override public void applyx() {
try (Transaction tx = ignite.transactions().txStart(TransactionConcurrency.PESSIMISTIC, isolation,
timeout, keys.size())) {

Expand All @@ -204,7 +206,9 @@ private void checkCauseObject(
tx.commit();
}
catch (Exception e) {
ex.compareAndSet(null, e);
// TransactionDeadlockException raised at least for one transaction involved in the deadlock
if (X.hasCause(e, TransactionDeadlockException.class))
ex.compareAndSet(null, e);
}
}
}, 2, "tx");
Expand Down Expand Up @@ -268,7 +272,7 @@ static class Account implements Serializable {
/**
* Change balance by specified amount.
*
* @param amount Amount to add to balance (may be negative).
* @param amount Amount to add to balance (maybe negative).
*/
void update(double amount) {
balance += amount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@
import org.junit.Test;

import static org.apache.ignite.IgniteSystemProperties.IGNITE_TX_DEADLOCK_DETECTION_TIMEOUT;
import static org.apache.ignite.IgniteSystemProperties.getInteger;
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;

/**
*
*/
@WithSystemProperty(key = IGNITE_TX_DEADLOCK_DETECTION_TIMEOUT, value = "1200000")
public class TxDeadlockDetectionNoHangsTest extends GridCommonAbstractTest {
/** Nodes count. */
private static final int NODES_CNT = 3;
Expand Down Expand Up @@ -85,19 +85,6 @@ public class TxDeadlockDetectionNoHangsTest extends GridCommonAbstractTest {
stopAllGrids();
}

/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();

GridTestUtils.setFieldValue(TxDeadlockDetection.class, "deadLockTimeout", (int)(getTestTimeout() * 2));
}

/** {@inheritDoc} */
@Override protected void afterTestsStopped() throws Exception {
GridTestUtils.setFieldValue(TxDeadlockDetection.class, "deadLockTimeout",
getInteger(IGNITE_TX_DEADLOCK_DETECTION_TIMEOUT, 60000));
}

/** {@inheritDoc} */
@Override protected long getTestTimeout() {
return 10 * 60 * 1000;
Expand Down
Loading