diff --git a/common/src/test/java/org/apache/seata/common/lock/ResourceLockTest.java b/common/src/test/java/org/apache/seata/common/lock/ResourceLockTest.java index 7b5ecd893fe..1ceee9ca8cb 100644 --- a/common/src/test/java/org/apache/seata/common/lock/ResourceLockTest.java +++ b/common/src/test/java/org/apache/seata/common/lock/ResourceLockTest.java @@ -16,10 +16,13 @@ */ package org.apache.seata.common.lock; +import org.apache.seata.common.util.CollectionUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.concurrent.ConcurrentHashMap; + import static org.junit.jupiter.api.Assertions.*; @ExtendWith(MockitoExtension.class) @@ -55,6 +58,26 @@ public void testMultipleObtainAndClose() { assertFalse(resourceLock.isHeldByCurrentThread(), "Lock should be released after second try-with-resources"); } + @Test + public void testResourceLockAutoRemovalFromMap() { + ConcurrentHashMap lockMap = new ConcurrentHashMap<>(); + String key = "testKey"; + // Use try-with-resources to obtain and release the lock + try (ResourceLock ignored = CollectionUtils.computeIfAbsent(lockMap, key, k -> new ResourceLock()).obtain()) { + // Do something while holding the lock + assertTrue(lockMap.containsKey(key)); + assertTrue(lockMap.get(key).isHeldByCurrentThread()); + } finally { + assertFalse(lockMap.get(key).isHeldByCurrentThread()); + assertTrue(lockMap.containsKey(key)); + // Remove the lock from the map + lockMap.remove(key); + assertFalse(lockMap.containsKey(key)); + } + // Ensure the lock is removed from the map + assertFalse(lockMap.containsKey(key)); + } + @Test public void testConcurrentLocking() throws InterruptedException { ResourceLock resourceLock = new ResourceLock(); diff --git a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/LoopContextHolder.java b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/LoopContextHolder.java index 39d9a54bbf3..830d0212de2 100644 --- a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/LoopContextHolder.java +++ b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/LoopContextHolder.java @@ -47,8 +47,7 @@ public static LoopContextHolder getCurrent(ProcessContext context, boolean force DomainConstants.VAR_NAME_CURRENT_LOOP_CONTEXT_HOLDER); if (null == loopContextHolder && forceCreate) { - try (ResourceLock lock = CollectionUtils.computeIfAbsent(CONTEXT_LOCK_MAP, context, k -> new ResourceLock()); - ResourceLock ignored = lock.obtain()) { + try (ResourceLock ignored = CollectionUtils.computeIfAbsent(CONTEXT_LOCK_MAP, context, k -> new ResourceLock()).obtain()) { loopContextHolder = (LoopContextHolder)context.getVariable( DomainConstants.VAR_NAME_CURRENT_LOOP_CONTEXT_HOLDER); if (null == loopContextHolder) {