From a8bab1ca1b50969f3075f3fcf05dcd5893ccc247 Mon Sep 17 00:00:00 2001 From: Sergey Chugunov Date: Thu, 2 Apr 2026 16:01:11 +0300 Subject: [PATCH 1/2] IGNITE-28242 Move cp readlock up in call stack to ensure correct lock acquisition ordering --- .../processors/cache/GridCacheMapEntry.java | 4 --- .../distributed/near/GridNearTxLocal.java | 35 +++++++++++-------- 2 files changed, 21 insertions(+), 18 deletions(-) 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 da6f47073df88..4b2cb3ff27588 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 @@ -457,8 +457,6 @@ protected GridDhtLocalPartition localPartition() { boolean deferred = false; GridCacheVersion ver0 = null; - cctx.shared().database().checkpointReadLock(); - lockEntry(); try { @@ -494,8 +492,6 @@ protected GridDhtLocalPartition localPartition() { } finally { unlockEntry(); - - cctx.shared().database().checkpointReadUnlock(); } if (obsolete) { 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 3c79a2f908364..a37492fffa4e5 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 @@ -2391,21 +2391,28 @@ private Collection enlistRead( optimistic() ? accessPolicy(cacheCtx, txKey, expiryPlc) : null; if (needReadVer) { - getRes = primaryLocal(entry) ? - entry.innerGetVersioned( - null, - this, - /*metrics*/true, - /*event*/true, - null, - resolveTaskName(), - accessPlc, - !deserializeBinary, - null) : null; + cctx.database().checkpointReadLock(); - if (getRes != null) { - val = getRes.value(); - readVer = getRes.version(); + try { + getRes = primaryLocal(entry) ? + entry.innerGetVersioned( + null, + this, + /*metrics*/true, + /*event*/true, + null, + resolveTaskName(), + accessPlc, + !deserializeBinary, + null) : null; + + if (getRes != null) { + val = getRes.value(); + readVer = getRes.version(); + } + } + finally { + cctx.database().checkpointReadUnlock(); } } else { From b3c8d4e6610daeaa01d46ac00517b3ba3e2e76ff Mon Sep 17 00:00:00 2001 From: Sergey Chugunov Date: Fri, 3 Apr 2026 15:15:58 +0300 Subject: [PATCH 2/2] IGNITE-28242 Add cp readlock to other places after test report analysis --- .../dht/GridDhtTxLocalAdapter.java | 24 ++++--- .../distributed/near/GridNearTxLocal.java | 64 ++++++++----------- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java index e8dfb2b1f6fb7..d04b7250e2729 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java @@ -589,18 +589,24 @@ IgniteInternalFuture lockAllAsync( if (txEntry == null) { GridDhtCacheEntry cached; - while (true) { - try { - cached = dhtCache.entryExx(key, topVer); + cctx.database().checkpointReadLock(); - cached.unswap(read); + try { + while (true) { + try { + cached = dhtCache.entryExx(key, topVer); - break; - } - catch (GridCacheEntryRemovedException ignore) { - if (log.isDebugEnabled()) - log.debug("Get removed entry: " + key); + cached.unswap(read); + + break; + } + catch (GridCacheEntryRemovedException ignore) { + if (log.isDebugEnabled()) + log.debug("Get removed entry: " + key); + } } + } finally { + cctx.database().checkpointReadUnlock(); } addActiveCache(dhtCache.context(), false); 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 a37492fffa4e5..194fbb1353d0c 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 @@ -1251,29 +1251,29 @@ private boolean enlistWriteEntry(GridCacheContext cacheCtx, GridCacheEntryEx entry = entryEx(cacheCtx, txKey, entryTopVer != null ? entryTopVer : topologyVersion()); try { - entry.unswap(false); - - // Check if lock is being explicitly acquired by the same thread. - if (!implicit && cctx.kernalContext().config().isCacheSanityCheckEnabled() && - entry.lockedByThread(threadId, xidVer)) { - throw new IgniteCheckedException("Cannot access key within transaction if lock is " + - "externally held [key=" + CU.value(cacheKey, cacheCtx, false) + - ", entry=" + entry + - ", xidVer=" + xidVer + - ", threadId=" + threadId + - ", locNodeId=" + cctx.localNodeId() + ']'); - } - CacheObject old = null; GridCacheVersion readVer = null; - if (optimistic() && !implicit()) { - try { - if (needReadVer) { - if (primaryLocal(entry)) { - cctx.database().checkpointReadLock(); + cctx.database().checkpointReadLock(); - try { + try { + entry.unswap(false); + + // Check if lock is being explicitly acquired by the same thread. + if (!implicit && cctx.kernalContext().config().isCacheSanityCheckEnabled() && + entry.lockedByThread(threadId, xidVer)) { + throw new IgniteCheckedException("Cannot access key within transaction if lock is " + + "externally held [key=" + CU.value(cacheKey, cacheCtx, false) + + ", entry=" + entry + + ", xidVer=" + xidVer + + ", threadId=" + threadId + + ", locNodeId=" + cctx.localNodeId() + ']'); + } + + if (optimistic() && !implicit()) { + try { + if (needReadVer) { + if (primaryLocal(entry)) { EntryGetResult res = entry.innerGetVersioned( null, this, @@ -1290,15 +1290,8 @@ private boolean enlistWriteEntry(GridCacheContext cacheCtx, readVer = res.version(); } } - finally { - cctx.database().checkpointReadUnlock(); - } } - } - else { - cctx.database().checkpointReadLock(); - - try { + else { old = entry.innerGet( null, this, @@ -1310,19 +1303,18 @@ private boolean enlistWriteEntry(GridCacheContext cacheCtx, null, keepBinary); } - finally { - cctx.database().checkpointReadUnlock(); - } } - } - catch (ClusterTopologyCheckedException e) { - entry.touch(); + catch (ClusterTopologyCheckedException e) { + entry.touch(); - throw e; + throw e; + } } + else + old = entry.rawGet(); + } finally { + cctx.database().checkpointReadUnlock(); } - else - old = entry.rawGet(); final GridCacheOperation op = rmv ? DELETE : entryProc != null ? TRANSFORM : old != null ? UPDATE : CREATE;