From 2462e2b306fd0c9c50dbe99f01b5d8644617d5c3 Mon Sep 17 00:00:00 2001 From: lightClouds917 Date: Thu, 20 Feb 2025 20:09:51 +0800 Subject: [PATCH 1/9] saga module:ResourceLock replace synchronized --- .../java/io/seata/saga/proctrl/ProcessContext.java | 6 ++++++ .../seata/saga/proctrl/impl/ProcessContextImpl.java | 7 ++++++- .../engine/pcext/handlers/ChoiceStateHandler.java | 5 ++++- .../interceptors/ServiceTaskHandlerInterceptor.java | 3 ++- .../saga/engine/pcext/utils/CompensationHolder.java | 4 ++-- .../saga/engine/pcext/utils/LoopContextHolder.java | 8 +++++++- .../seata/saga/engine/pcext/utils/LoopTaskUtils.java | 3 ++- .../engine/repo/impl/StateMachineRepositoryImpl.java | 10 ++++++++-- .../org/apache/seata/saga/proctrl/ProcessContext.java | 8 ++++++++ .../saga/proctrl/eventing/impl/DirectEventBus.java | 5 ++++- .../seata/saga/proctrl/impl/ProcessContextImpl.java | 7 +++++++ .../engine/invoker/impl/SpringBeanServiceInvoker.java | 6 +++--- .../statelang/domain/impl/ServiceTaskStateImpl.java | 11 +++++++++++ 13 files changed, 70 insertions(+), 13 deletions(-) diff --git a/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java b/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java index 424c0cd7747..64baedcf3d2 100644 --- a/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java +++ b/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java @@ -97,4 +97,10 @@ public interface ProcessContext extends org.apache.seata.saga.proctrl.ProcessCon * @return the get instruction */ T getInstruction(Class clazz); + + /** + * Gets get lock. + * @return the lock of the current process context + */ + ResourceLock getLock(); } diff --git a/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java b/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java index ee7bc9820f6..6cc8aa11f82 100644 --- a/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java +++ b/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java @@ -30,6 +30,7 @@ public class ProcessContextImpl implements HierarchicalProcessContext, ProcessContext { private final org.apache.seata.saga.proctrl.HierarchicalProcessContext actual; + private final ResourceLock LOCK = new ResourceLock(); private ProcessContextImpl(org.apache.seata.saga.proctrl.HierarchicalProcessContext target) { this.actual = target; @@ -95,6 +96,11 @@ public T getInstruction(Class clazz) { return actual.getInstruction(clazz); } + @Override + public ResourceLock getLock() { + return LOCK; + } + @Override public boolean hasVariableLocal(String name) { return actual.hasVariableLocal(name); @@ -129,7 +135,6 @@ public void setParent(ProcessContext parent) { public String toString() { return actual.toString(); } - public static ProcessContextImpl wrap(org.apache.seata.saga.proctrl.HierarchicalProcessContext target) { return new ProcessContextImpl(target); } diff --git a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/handlers/ChoiceStateHandler.java b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/handlers/ChoiceStateHandler.java index ee6fac0c137..2013bf22e6c 100644 --- a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/handlers/ChoiceStateHandler.java +++ b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/handlers/ChoiceStateHandler.java @@ -21,6 +21,7 @@ import java.util.Map; import org.apache.seata.common.exception.FrameworkErrorCode; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.common.util.StringUtils; import org.apache.seata.saga.engine.StateMachineConfig; import org.apache.seata.saga.engine.exception.EngineExecutionException; @@ -42,6 +43,8 @@ */ public class ChoiceStateHandler implements StateHandler { + private final ResourceLock choiceStateLock = new ResourceLock(); + @Override public void process(ProcessContext context) throws EngineExecutionException { @@ -50,7 +53,7 @@ public void process(ProcessContext context) throws EngineExecutionException { Map choiceEvaluators = choiceState.getChoiceEvaluators(); if (choiceEvaluators == null) { - synchronized (choiceState) { + try (ResourceLock ignored = choiceStateLock.obtain()) { choiceEvaluators = choiceState.getChoiceEvaluators(); if (choiceEvaluators == null) { diff --git a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/interceptors/ServiceTaskHandlerInterceptor.java b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/interceptors/ServiceTaskHandlerInterceptor.java index 5091fc584d6..ba749b28c78 100644 --- a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/interceptors/ServiceTaskHandlerInterceptor.java +++ b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/interceptors/ServiceTaskHandlerInterceptor.java @@ -23,6 +23,7 @@ import org.apache.seata.common.exception.FrameworkErrorCode; import org.apache.seata.common.loader.LoadLevel; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.common.util.CollectionUtils; import org.apache.seata.common.util.StringUtils; import org.apache.seata.saga.engine.StateMachineConfig; @@ -312,7 +313,7 @@ private void decideExecutionStatus(ProcessContext context, StateInstance stateIn Map statusEvaluators = state.getStatusEvaluators(); if (statusEvaluators == null) { - synchronized (state) { + try (ResourceLock ignored = state.getResourceLock().obtain()) { statusEvaluators = state.getStatusEvaluators(); if (statusEvaluators == null) { statusEvaluators = new LinkedHashMap<>(statusMatchList.size()); diff --git a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/CompensationHolder.java b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/CompensationHolder.java index b4d748646ae..97e30379c85 100644 --- a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/CompensationHolder.java +++ b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/CompensationHolder.java @@ -23,6 +23,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.seata.common.exception.FrameworkErrorCode; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.common.util.CollectionUtils; import org.apache.seata.common.util.StringUtils; import org.apache.seata.saga.engine.exception.EngineExecutionException; @@ -65,8 +66,7 @@ public static CompensationHolder getCurrent(ProcessContext context, boolean forc CompensationHolder compensationholder = (CompensationHolder)context.getVariable( DomainConstants.VAR_NAME_CURRENT_COMPENSATION_HOLDER); if (compensationholder == null && forceCreate) { - synchronized (context) { - + try (ResourceLock ignored = context.getLock().obtain()) { compensationholder = (CompensationHolder)context.getVariable( DomainConstants.VAR_NAME_CURRENT_COMPENSATION_HOLDER); if (compensationholder == null) { 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 519b0a02372..d0686124ae5 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 @@ -20,6 +20,7 @@ import java.util.Stack; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.saga.proctrl.ProcessContext; import org.apache.seata.saga.statelang.domain.DomainConstants; @@ -37,13 +38,14 @@ public class LoopContextHolder { private final Stack loopCounterStack = new Stack<>(); private final Stack forwardCounterStack = new Stack<>(); private Collection collection; + private final ResourceLock lock = new ResourceLock(); public static LoopContextHolder getCurrent(ProcessContext context, boolean forceCreate) { LoopContextHolder loopContextHolder = (LoopContextHolder)context.getVariable( DomainConstants.VAR_NAME_CURRENT_LOOP_CONTEXT_HOLDER); if (null == loopContextHolder && forceCreate) { - synchronized (context) { + try (ResourceLock ignored = context.getLock().obtain()) { loopContextHolder = (LoopContextHolder)context.getVariable( DomainConstants.VAR_NAME_CURRENT_LOOP_CONTEXT_HOLDER); if (null == loopContextHolder) { @@ -102,4 +104,8 @@ public Collection getCollection() { public void setCollection(Collection collection) { this.collection = collection; } + + public ResourceLock getLock() { + return lock; + } } diff --git a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/LoopTaskUtils.java b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/LoopTaskUtils.java index f9500eb3337..bad0153297c 100644 --- a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/LoopTaskUtils.java +++ b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/LoopTaskUtils.java @@ -25,6 +25,7 @@ import java.util.stream.Collectors; import org.apache.seata.common.exception.FrameworkErrorCode; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.common.util.CollectionUtils; import org.apache.seata.common.util.NumberUtils; import org.apache.seata.common.util.StringUtils; @@ -225,7 +226,7 @@ public static boolean isCompletionConditionSatisfied(ProcessContext context) { int nrOfCompletedInstances = currentLoopContext.getNrOfCompletedInstances().get(); if (!currentLoopContext.isCompletionConditionSatisfied()) { - synchronized (currentLoopContext) { + try (ResourceLock ignored = currentLoopContext.getLock().obtain()) { if (!currentLoopContext.isCompletionConditionSatisfied()) { Map stateMachineContext = (Map)context.getVariable( DomainConstants.VAR_NAME_STATEMACHINE_CONTEXT); diff --git a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/repo/impl/StateMachineRepositoryImpl.java b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/repo/impl/StateMachineRepositoryImpl.java index 0def5110ecf..f7407eca4d2 100644 --- a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/repo/impl/StateMachineRepositoryImpl.java +++ b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/repo/impl/StateMachineRepositoryImpl.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.common.util.CollectionUtils; import org.apache.seata.common.util.StringUtils; import org.apache.seata.saga.engine.repo.StateMachineRepository; @@ -57,7 +58,7 @@ public StateMachine getStateMachineById(String stateMachineId) { Item item = CollectionUtils.computeIfAbsent(stateMachineMapById, stateMachineId, key -> new Item()); if (item.getValue() == null && stateLangStore != null) { - synchronized (item) { + try (ResourceLock ignored = item.getLock().obtain()) { if (item.getValue() == null) { StateMachine stateMachine = stateLangStore.getStateMachineById(stateMachineId); if (stateMachine != null) { @@ -85,7 +86,7 @@ public StateMachine getStateMachine(String stateMachineName, String tenantId) { Item item = CollectionUtils.computeIfAbsent(stateMachineMapByNameAndTenant, stateMachineName + "_" + tenantId, key -> new Item()); if (item.getValue() == null && stateLangStore != null) { - synchronized (item) { + try (ResourceLock ignored = item.getLock().obtain()) { if (item.getValue() == null) { StateMachine stateMachine = stateLangStore.getLastVersionStateMachine(stateMachineName, tenantId); if (stateMachine != null) { @@ -218,6 +219,7 @@ public void setJsonParserName(String jsonParserName) { private static class Item { private StateMachine value; + private final ResourceLock lock = new ResourceLock(); private Item() { } @@ -233,5 +235,9 @@ public StateMachine getValue() { public void setValue(StateMachine value) { this.value = value; } + + public ResourceLock getLock() { + return lock; + } } } diff --git a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/ProcessContext.java b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/ProcessContext.java index 544f2f6c4c3..b8d588f9291 100644 --- a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/ProcessContext.java +++ b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/ProcessContext.java @@ -16,6 +16,8 @@ */ package org.apache.seata.saga.proctrl; +import org.apache.seata.common.lock.ResourceLock; + import java.util.Map; /** @@ -94,4 +96,10 @@ public interface ProcessContext { * @return the get instruction */ T getInstruction(Class clazz); + + /** + * Gets get lock. + * @return the lock of the current process context + */ + ResourceLock getLock(); } diff --git a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/eventing/impl/DirectEventBus.java b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/eventing/impl/DirectEventBus.java index 2ff2fb50bbc..aec88942256 100644 --- a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/eventing/impl/DirectEventBus.java +++ b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/eventing/impl/DirectEventBus.java @@ -20,6 +20,7 @@ import java.util.Stack; import org.apache.seata.common.exception.FrameworkException; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.common.util.CollectionUtils; import org.apache.seata.saga.proctrl.ProcessContext; import org.apache.seata.saga.proctrl.eventing.EventConsumer; @@ -36,6 +37,8 @@ public class DirectEventBus extends AbstractEventBus { private static final String VAR_NAME_SYNC_EXE_STACK = "_sync_execution_stack_"; + private final ResourceLock contextLock = new ResourceLock(); + @Override public boolean offer(ProcessContext context) throws FrameworkException { List eventHandlers = getEventConsumers(context.getClass()); @@ -49,7 +52,7 @@ public boolean offer(ProcessContext context) throws FrameworkException { boolean isFirstEvent = false; Stack currentStack = (Stack)context.getVariable(VAR_NAME_SYNC_EXE_STACK); if (currentStack == null) { - synchronized (context) { + try (ResourceLock ignored = contextLock.obtain()) { currentStack = (Stack)context.getVariable(VAR_NAME_SYNC_EXE_STACK); if (currentStack == null) { currentStack = new Stack<>(); diff --git a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java index 2d8612d4c5c..5f2449bdb71 100644 --- a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java +++ b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.saga.proctrl.HierarchicalProcessContext; import org.apache.seata.saga.proctrl.Instruction; import org.apache.seata.saga.proctrl.ProcessContext; @@ -34,6 +35,7 @@ public class ProcessContextImpl implements HierarchicalProcessContext, ProcessCo private Map variables = new ConcurrentHashMap<>(); private Instruction instruction; private ProcessContext parent; + private final ResourceLock LOCK = new ResourceLock(); @Override public Object getVariable(String name) { @@ -125,6 +127,11 @@ public T getInstruction(Class clazz) { return (T)instruction; } + @Override + public ResourceLock getLock() { + return LOCK; + } + @Override public boolean hasVariableLocal(String name) { return variables.containsKey(name); diff --git a/saga/seata-saga-spring/src/main/java/org/apache/seata/saga/engine/invoker/impl/SpringBeanServiceInvoker.java b/saga/seata-saga-spring/src/main/java/org/apache/seata/saga/engine/invoker/impl/SpringBeanServiceInvoker.java index d97f9c3972d..9ad82ae3b23 100644 --- a/saga/seata-saga-spring/src/main/java/org/apache/seata/saga/engine/invoker/impl/SpringBeanServiceInvoker.java +++ b/saga/seata-saga-spring/src/main/java/org/apache/seata/saga/engine/invoker/impl/SpringBeanServiceInvoker.java @@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.seata.common.exception.FrameworkErrorCode; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.common.util.CollectionUtils; import org.apache.seata.saga.engine.exception.EngineExecutionException; import org.apache.seata.saga.engine.invoker.ServiceInvoker; @@ -56,6 +57,7 @@ public class SpringBeanServiceInvoker implements ServiceInvoker, ApplicationCont private ApplicationContext applicationContext; private ThreadPoolExecutor threadPoolExecutor; private String sagaJsonParser; + private final ResourceLock stateLock = new ResourceLock(); @Override public Object invoke(ServiceTaskState serviceTaskState, Object... input) throws Throwable { @@ -92,12 +94,11 @@ public void run() { } protected Object doInvoke(ServiceTaskStateImpl state, Object[] input) throws Throwable { - Object bean = applicationContext.getBean(state.getServiceName()); Method method = state.getMethod(); if (method == null) { - synchronized (state) { + try (ResourceLock ignored = stateLock.obtain()) { method = state.getMethod(); if (method == null) { method = findMethod(bean.getClass(), state.getServiceMethod(), state.getParameterTypes()); @@ -112,7 +113,6 @@ protected Object doInvoke(ServiceTaskStateImpl state, Object[] input) throws Thr throw new EngineExecutionException( "No such method[" + state.getServiceMethod() + "] on BeanClass[" + bean.getClass() + "]", FrameworkErrorCode.NoSuchMethod); - } Object[] args = new Object[method.getParameterCount()]; diff --git a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/domain/impl/ServiceTaskStateImpl.java b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/domain/impl/ServiceTaskStateImpl.java index aa16d60b83b..caed8e96bbc 100644 --- a/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/domain/impl/ServiceTaskStateImpl.java +++ b/saga/seata-saga-statelang/src/main/java/org/apache/seata/saga/statelang/domain/impl/ServiceTaskStateImpl.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.saga.statelang.domain.StateType; import org.apache.seata.saga.statelang.domain.ServiceTaskState; @@ -36,6 +37,7 @@ public class ServiceTaskStateImpl extends AbstractTaskState implements ServiceTa private Method method; private Map statusEvaluators; private boolean isAsync; + private final ResourceLock resourceLock = new ResourceLock(); public ServiceTaskStateImpl() { setType(StateType.SERVICE_TASK); @@ -100,4 +102,13 @@ public boolean isAsync() { public void setAsync(boolean async) { isAsync = async; } + + /** + * Get the ResourceLock for statusEvaluators + * + * @return the ResourceLock instance + */ + public ResourceLock getResourceLock() { + return resourceLock; + } } From 5bcb3572ce8ef78a534949fe1a1ff3e12e9a8cb5 Mon Sep 17 00:00:00 2001 From: lightClouds917 Date: Fri, 21 Feb 2025 09:25:08 +0800 Subject: [PATCH 2/9] saga module:fix import,LOCK to lock --- .../src/main/java/io/seata/saga/proctrl/ProcessContext.java | 1 + .../java/io/seata/saga/proctrl/impl/ProcessContextImpl.java | 1 + .../apache/seata/saga/proctrl/impl/ProcessContextImpl.java | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java b/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java index 64baedcf3d2..9698d5b442c 100644 --- a/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java +++ b/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java @@ -18,6 +18,7 @@ import java.util.Map; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.saga.proctrl.Instruction; /** diff --git a/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java b/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java index 6cc8aa11f82..d4856fd11ba 100644 --- a/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java +++ b/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java @@ -20,6 +20,7 @@ import io.seata.saga.proctrl.HierarchicalProcessContext; import io.seata.saga.proctrl.ProcessContext; +import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.saga.proctrl.Instruction; /** diff --git a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java index 5f2449bdb71..4dd63383679 100644 --- a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java +++ b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java @@ -35,7 +35,7 @@ public class ProcessContextImpl implements HierarchicalProcessContext, ProcessCo private Map variables = new ConcurrentHashMap<>(); private Instruction instruction; private ProcessContext parent; - private final ResourceLock LOCK = new ResourceLock(); + private final ResourceLock lock = new ResourceLock(); @Override public Object getVariable(String name) { @@ -129,7 +129,7 @@ public T getInstruction(Class clazz) { @Override public ResourceLock getLock() { - return LOCK; + return lock; } @Override From 5448409334993427529b2a25c053c311fb1c1acd Mon Sep 17 00:00:00 2001 From: lightClouds917 Date: Fri, 21 Feb 2025 09:45:48 +0800 Subject: [PATCH 3/9] saga module:LOCK to lock --- .../java/io/seata/saga/proctrl/impl/ProcessContextImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java b/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java index d4856fd11ba..9ef2f38c87f 100644 --- a/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java +++ b/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java @@ -31,7 +31,7 @@ public class ProcessContextImpl implements HierarchicalProcessContext, ProcessContext { private final org.apache.seata.saga.proctrl.HierarchicalProcessContext actual; - private final ResourceLock LOCK = new ResourceLock(); + private final ResourceLock lock = new ResourceLock(); private ProcessContextImpl(org.apache.seata.saga.proctrl.HierarchicalProcessContext target) { this.actual = target; @@ -99,7 +99,7 @@ public T getInstruction(Class clazz) { @Override public ResourceLock getLock() { - return LOCK; + return lock; } @Override From 6c34225516adee79b2e8aaa739c9b54bf48c22ad Mon Sep 17 00:00:00 2001 From: lightClouds917 Date: Fri, 21 Feb 2025 17:45:07 +0800 Subject: [PATCH 4/9] update .md --- changes/en-us/2.x.md | 2 ++ changes/zh-cn/2.x.md | 3 +++ 2 files changed, 5 insertions(+) diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index 2e8e699f302..2e8dfa70084 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -11,6 +11,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#7038](https://github.com/apache/incubator-seata/pull/7038)] support fury serializer - [[#7133](https://github.com/apache/incubator-seata/pull/7133)] Implement scheduled handling for end status transaction - [[#7171](https://github.com/apache/incubator-seata/pull/7171)] support EpollEventLoopGroup in client +- [[#7174](https://github.com/apache/incubator-seata/pull/7174)] replace the usages of synchronized with ReentrantLock at saga module ### bugfix: @@ -78,5 +79,6 @@ Thanks to these contributors for their code commits. Please report an unintended - [xingfudeshi](https://github.com/xingfudeshi) - [YongGoose](https://github.com/YongGoose) - [Monilnarang](https://github.com/Monilnarang) +- [lightClouds917](https://github.com/lightClouds917) Also, we receive many valuable issues, questions and advices from our community. Thanks for you all. diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index f661d8c1671..20f9a8b1759 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -11,6 +11,8 @@ - [[#7038](https://github.com/apache/incubator-seata/pull/7038)] 支持Fury序列化器 - [[#7133](https://github.com/apache/incubator-seata/pull/7133)] 实现对残留的end状态事务定时处理 - [[#7171](https://github.com/apache/incubator-seata/pull/7171)] 客户端支持 EpollEventLoopGroup +- [[#7174](https://github.com/apache/incubator-seata/pull/7174)] saga模块synchronized替换为ReentrantLock + ### bugfix: @@ -78,5 +80,6 @@ - [xingfudeshi](https://github.com/xingfudeshi) - [YongGoose](https://github.com/YongGoose) - [Monilnarang](https://github.com/Monilnarang) +- [lightClouds917](https://github.com/lightClouds917) 同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。 From fbdb9c1bb1a0ae7dfa77d534b4bbb55e5dddbd44 Mon Sep 17 00:00:00 2001 From: lightClouds917 Date: Tue, 4 Mar 2025 20:06:27 +0800 Subject: [PATCH 5/9] optimize the interface --- .../seata/saga/engine/pcext/utils/LoopContextHolder.java | 6 +++++- .../java/org/apache/seata/saga/proctrl/ProcessContext.java | 7 ------- 2 files changed, 5 insertions(+), 8 deletions(-) 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 d0686124ae5..6702a71fc9a 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 @@ -18,6 +18,7 @@ import java.util.Collection; import java.util.Stack; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import org.apache.seata.common.lock.ResourceLock; @@ -39,19 +40,22 @@ public class LoopContextHolder { private final Stack forwardCounterStack = new Stack<>(); private Collection collection; private final ResourceLock lock = new ResourceLock(); + private static final ConcurrentHashMap LOCK_MAP = new ConcurrentHashMap<>(); public static LoopContextHolder getCurrent(ProcessContext context, boolean forceCreate) { LoopContextHolder loopContextHolder = (LoopContextHolder)context.getVariable( DomainConstants.VAR_NAME_CURRENT_LOOP_CONTEXT_HOLDER); if (null == loopContextHolder && forceCreate) { - try (ResourceLock ignored = context.getLock().obtain()) { + try (ResourceLock ignored = LOCK_MAP.computeIfAbsent(context, k -> new ResourceLock()).obtain()) { loopContextHolder = (LoopContextHolder)context.getVariable( DomainConstants.VAR_NAME_CURRENT_LOOP_CONTEXT_HOLDER); if (null == loopContextHolder) { loopContextHolder = new LoopContextHolder(); context.setVariable(DomainConstants.VAR_NAME_CURRENT_LOOP_CONTEXT_HOLDER, loopContextHolder); } + } finally { + LOCK_MAP.remove(context); } } return loopContextHolder; diff --git a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/ProcessContext.java b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/ProcessContext.java index b8d588f9291..69b3762777d 100644 --- a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/ProcessContext.java +++ b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/ProcessContext.java @@ -16,8 +16,6 @@ */ package org.apache.seata.saga.proctrl; -import org.apache.seata.common.lock.ResourceLock; - import java.util.Map; /** @@ -97,9 +95,4 @@ public interface ProcessContext { */ T getInstruction(Class clazz); - /** - * Gets get lock. - * @return the lock of the current process context - */ - ResourceLock getLock(); } From 06fc30521842b5d85a84630b632e67e1b1bf6183 Mon Sep 17 00:00:00 2001 From: lightClouds917 Date: Tue, 4 Mar 2025 20:10:07 +0800 Subject: [PATCH 6/9] optimize the interface --- .../main/java/io/seata/saga/proctrl/ProcessContext.java | 6 ------ .../io/seata/saga/proctrl/impl/ProcessContextImpl.java | 7 ------- 2 files changed, 13 deletions(-) diff --git a/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java b/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java index 9698d5b442c..0bfe1cdede9 100644 --- a/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java +++ b/compatible/src/main/java/io/seata/saga/proctrl/ProcessContext.java @@ -18,7 +18,6 @@ import java.util.Map; -import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.saga.proctrl.Instruction; /** @@ -99,9 +98,4 @@ public interface ProcessContext extends org.apache.seata.saga.proctrl.ProcessCon */ T getInstruction(Class clazz); - /** - * Gets get lock. - * @return the lock of the current process context - */ - ResourceLock getLock(); } diff --git a/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java b/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java index 9ef2f38c87f..d9a30b8f306 100644 --- a/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java +++ b/compatible/src/main/java/io/seata/saga/proctrl/impl/ProcessContextImpl.java @@ -20,7 +20,6 @@ import io.seata.saga.proctrl.HierarchicalProcessContext; import io.seata.saga.proctrl.ProcessContext; -import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.saga.proctrl.Instruction; /** @@ -31,7 +30,6 @@ public class ProcessContextImpl implements HierarchicalProcessContext, ProcessContext { private final org.apache.seata.saga.proctrl.HierarchicalProcessContext actual; - private final ResourceLock lock = new ResourceLock(); private ProcessContextImpl(org.apache.seata.saga.proctrl.HierarchicalProcessContext target) { this.actual = target; @@ -97,11 +95,6 @@ public T getInstruction(Class clazz) { return actual.getInstruction(clazz); } - @Override - public ResourceLock getLock() { - return lock; - } - @Override public boolean hasVariableLocal(String name) { return actual.hasVariableLocal(name); From 4e4238aa03296b196e2a0aaa04f6e79b414c51d6 Mon Sep 17 00:00:00 2001 From: lightClouds917 Date: Wed, 5 Mar 2025 09:02:48 +0800 Subject: [PATCH 7/9] optimize the interface --- .../apache/seata/saga/proctrl/impl/ProcessContextImpl.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java index 4dd63383679..ae8853b5495 100644 --- a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java +++ b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java @@ -127,11 +127,6 @@ public T getInstruction(Class clazz) { return (T)instruction; } - @Override - public ResourceLock getLock() { - return lock; - } - @Override public boolean hasVariableLocal(String name) { return variables.containsKey(name); From 1602840052d636736a1781bf218c5b4dee863a68 Mon Sep 17 00:00:00 2001 From: lightClouds917 Date: Wed, 5 Mar 2025 09:04:11 +0800 Subject: [PATCH 8/9] optimize the interface --- .../org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java index ae8853b5495..2d8612d4c5c 100644 --- a/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java +++ b/saga/seata-saga-processctrl/src/main/java/org/apache/seata/saga/proctrl/impl/ProcessContextImpl.java @@ -21,7 +21,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.apache.seata.common.lock.ResourceLock; import org.apache.seata.saga.proctrl.HierarchicalProcessContext; import org.apache.seata.saga.proctrl.Instruction; import org.apache.seata.saga.proctrl.ProcessContext; @@ -35,7 +34,6 @@ public class ProcessContextImpl implements HierarchicalProcessContext, ProcessCo private Map variables = new ConcurrentHashMap<>(); private Instruction instruction; private ProcessContext parent; - private final ResourceLock lock = new ResourceLock(); @Override public Object getVariable(String name) { From 019de2ae450a134f212556592a8612087a6bd2e4 Mon Sep 17 00:00:00 2001 From: lightClouds917 Date: Wed, 5 Mar 2025 09:21:12 +0800 Subject: [PATCH 9/9] optimize the interface --- .../seata/saga/engine/pcext/utils/CompensationHolder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/CompensationHolder.java b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/CompensationHolder.java index 97e30379c85..84fce0b5a91 100644 --- a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/CompensationHolder.java +++ b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/CompensationHolder.java @@ -61,18 +61,22 @@ public class CompensationHolder { */ private Stack stateStackNeedCompensation = new Stack<>(); + private static final ConcurrentHashMap LOCK_MAP = new ConcurrentHashMap<>(); + public static CompensationHolder getCurrent(ProcessContext context, boolean forceCreate) { CompensationHolder compensationholder = (CompensationHolder)context.getVariable( DomainConstants.VAR_NAME_CURRENT_COMPENSATION_HOLDER); if (compensationholder == null && forceCreate) { - try (ResourceLock ignored = context.getLock().obtain()) { + try (ResourceLock ignored = LOCK_MAP.computeIfAbsent(context, k -> new ResourceLock()).obtain()) { compensationholder = (CompensationHolder)context.getVariable( DomainConstants.VAR_NAME_CURRENT_COMPENSATION_HOLDER); if (compensationholder == null) { compensationholder = new CompensationHolder(); context.setVariable(DomainConstants.VAR_NAME_CURRENT_COMPENSATION_HOLDER, compensationholder); } + } finally { + LOCK_MAP.remove(context); } } return compensationholder;