This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new ad5f17c7db7 IGNITE-28653 Fix failure on remove from PDS expired 
entries for onheap cache/near cache - Fixes #13117.
ad5f17c7db7 is described below

commit ad5f17c7db7daa3739a162522c312613974269d2
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Fri May 8 15:26:11 2026 +0300

    IGNITE-28653 Fix failure on remove from PDS expired entries for onheap 
cache/near cache - Fixes #13117.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../processors/cache/GridCacheMapEntry.java        | 24 +++++++++--
 .../cache/persistence/db/IgnitePdsWithTtlTest.java | 49 ++++++++++++++++++++++
 2 files changed, 70 insertions(+), 3 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 da6f47073df..b3af6e7b4d9 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
@@ -2308,9 +2308,10 @@ public abstract class GridCacheMapEntry extends 
GridMetadataAwareAdapter impleme
         boolean heap,
         boolean offheap,
         AffinityTopologyVersion topVer,
-        @Nullable IgniteCacheExpiryPolicy expiryPlc)
-        throws GridCacheEntryRemovedException, IgniteCheckedException {
+        @Nullable IgniteCacheExpiryPolicy expiryPlc
+    ) throws GridCacheEntryRemovedException, IgniteCheckedException {
         assert heap || offheap;
+        assert cctx.shared().database().checkpointLockIsHeldByThread();
 
         boolean rmv = false;
 
@@ -2377,7 +2378,17 @@ public abstract class GridCacheMapEntry extends 
GridMetadataAwareAdapter impleme
 
         AffinityTopologyVersion topVer = tx != null ? tx.topologyVersion() : 
cctx.affinity().affinityTopologyVersion();
 
-        return peek(true, false, topVer, null);
+        assert cctx.shared().database().checkpointLockIsHeldByThread() || 
!lockedByCurrentThread() :
+            "Lock order violation, checkpoint lock must be acquired before 
entry lock";
+
+        cctx.shared().database().checkpointReadLock();
+
+        try {
+            return peek(true, false, topVer, null);
+        }
+        finally {
+            cctx.shared().database().checkpointReadUnlock();
+        }
     }
 
     /**
@@ -3790,6 +3801,11 @@ public abstract class GridCacheMapEntry extends 
GridMetadataAwareAdapter impleme
     public final boolean visitable(CacheEntryPredicate[] filter) {
         boolean rmv = false;
 
+        assert cctx.shared().database().checkpointLockIsHeldByThread() || 
!lockedByCurrentThread() :
+            "Lock order violation, checkpoint lock must be acquired before 
entry lock";
+
+        cctx.shared().database().checkpointReadLock();
+
         try {
             lockEntry();
 
@@ -3826,6 +3842,8 @@ public abstract class GridCacheMapEntry extends 
GridMetadataAwareAdapter impleme
             return false;
         }
         finally {
+            cctx.shared().database().checkpointReadUnlock();
+
             if (rmv) {
                 onMarkedObsolete();
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsWithTtlTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsWithTtlTest.java
index 2b397a34d96..13e231d7ebc 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsWithTtlTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/IgnitePdsWithTtlTest.java
@@ -64,6 +64,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
 import org.junit.Test;
 
 import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
@@ -484,6 +485,54 @@ public class IgnitePdsWithTtlTest extends 
GridCommonAbstractTest {
         assertFalse("Failure handler should not be triggered.", 
failureHndTriggered);
     }
 
+    /** */
+    @Test
+    public void testNearCacheExpiredEntriesIteration() throws Exception {
+        IgniteEx srv = startGrids(2);
+        srv.cluster().state(ACTIVE);
+
+        IgniteCache<Object, Object> cache = srv.getOrCreateCache(new 
CacheConfiguration<>(DEFAULT_CACHE_NAME)
+            .setNearConfiguration(new NearCacheConfiguration<>())
+            .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new 
Duration(TimeUnit.MILLISECONDS, 1)))
+            .setEagerTtl(false)
+        );
+
+        for (int i = 0; i < 100; i++)
+            cache.put(i, "val");
+
+        doSleep(10); // Wait for expiration.
+
+        cache.clear();
+
+        assertEquals(0, cache.size());
+    }
+
+    /** */
+    @Test
+    public void testReplaceExpiredOnheapEntriesUnderTx() throws Exception {
+        IgniteEx srv = startGrid(0);
+        srv.cluster().state(ACTIVE);
+
+        IgniteCache<Object, Object> cache = srv.getOrCreateCache(new 
CacheConfiguration<>(DEFAULT_CACHE_NAME)
+            .setOnheapCacheEnabled(true)
+            .setAtomicityMode(TRANSACTIONAL)
+            .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new 
Duration(TimeUnit.MILLISECONDS, 1)))
+            .setEagerTtl(false)
+        );
+
+        cache.put(0, "val");
+
+        doSleep(10); // Wait for expiration.
+
+        try (Transaction tx = srv.transactions().txStart()) {
+            cache.replace(0, "val", "val1");
+
+            tx.commit();
+        }
+
+        assertNull(cache.get(0)); // Expired.
+    }
+
     /**
      *
      */

Reply via email to