This is an automated email from the ASF dual-hosted git repository.
jianbin pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git
The following commit(s) were added to refs/heads/2.x by this push:
new 49e99de508 optimize: replace synchronized with ReentrantLock in saga
module (#8008)
49e99de508 is described below
commit 49e99de50891cbf31f630e75cea1814e2e1198b0
Author: somil jain <[email protected]>
AuthorDate: Fri Mar 20 13:53:03 2026 +0530
optimize: replace synchronized with ReentrantLock in saga module (#8008)
---
changes/en-us/2.x.md | 2 ++
.../seata/saga/engine/pcext/handlers/ChoiceStateHandler.java | 5 ++++-
.../engine/pcext/interceptors/ServiceTaskHandlerInterceptor.java | 5 ++++-
.../apache/seata/saga/engine/pcext/utils/CompensationHolder.java | 5 ++++-
.../org/apache/seata/saga/engine/pcext/utils/EngineUtils.java | 5 ++++-
.../apache/seata/saga/engine/pcext/utils/LoopContextHolder.java | 5 ++++-
.../org/apache/seata/saga/engine/pcext/utils/LoopTaskUtils.java | 5 ++++-
.../org/apache/seata/saga/engine/pcext/utils/ParameterUtils.java | 7 +++++--
.../seata/saga/engine/repo/impl/StateMachineRepositoryImpl.java | 6 ++++--
.../apache/seata/saga/proctrl/eventing/impl/DirectEventBus.java | 5 ++++-
.../seata/saga/engine/invoker/impl/SpringBeanServiceInvoker.java | 8 ++++++--
11 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index 0b7fc3ef40..e3fd0e1531 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -45,6 +45,7 @@ Add changes here for all PR submitted to the 2.x branch.
- [[#7955](https://github.com/apache/incubator-seata/pull/7955)] change the
getProperty call to resolvePlaceholders
- [[#7971](https://github.com/apache/incubator-seata/pull/7971)] upgrade some
dependencies
- [[#7970](https://github.com/apache/incubator-seata/pull/7970)] Remove
unnecessary refreshLeader from ClusterController cluster endpoint
+- [[#8008](https://github.com/apache/incubator-seata/pull/8008)] replace
synchronized with ReentrantLock in saga module for Loom virtual thread
compatibility
- [[#8019](https://github.com/apache/incubator-seata/pull/8019)] mark
deprecated JSON parsers
@@ -80,6 +81,7 @@ Thanks to these contributors for their code commits. Please
report an unintended
- [xingfudeshi](https://github.com/xingfudeshi)
- [Sumit6307](https://github.com/Sumit6307)
- [xiaoxiangyeyu0](https://github.com/xiaoxiangyeyu0)
+- [somiljain](https://github.com/somiljain)
Also, we receive many valuable issues, questions and advices from our
community. Thanks for you all.
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 9f6f05b73a..b89d2c184a 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
@@ -17,6 +17,7 @@
package org.apache.seata.saga.engine.pcext.handlers;
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 @@ import java.util.Map;
*/
public class ChoiceStateHandler implements StateHandler {
+ private final ResourceLock CHOICE_LOCK = new ResourceLock();
+
@Override
public void process(ProcessContext context) throws
EngineExecutionException {
@@ -50,7 +53,7 @@ public class ChoiceStateHandler implements StateHandler {
Map<Object, String> choiceEvaluators =
choiceState.getChoiceEvaluators();
if (choiceEvaluators == null) {
- synchronized (choiceState) {
+ try (ResourceLock ignored = CHOICE_LOCK.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 bcbb498c6a..be34813435 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
@@ -18,6 +18,7 @@ package org.apache.seata.saga.engine.pcext.interceptors;
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;
@@ -61,6 +62,8 @@ public class ServiceTaskHandlerInterceptor implements
StateHandlerInterceptor {
private static final Logger LOGGER =
LoggerFactory.getLogger(ServiceTaskHandlerInterceptor.class);
+ private final ResourceLock STATUS_LOCK = new ResourceLock();
+
@Override
public boolean match(Class<? extends InterceptableStateHandler> clazz) {
return clazz != null
@@ -325,7 +328,7 @@ public class ServiceTaskHandlerInterceptor implements
StateHandlerInterceptor {
Map<Object, String> statusEvaluators =
state.getStatusEvaluators();
if (statusEvaluators == null) {
- synchronized (state) {
+ try (ResourceLock ignored = STATUS_LOCK.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 9bae5c1153..dfb669a08c 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
@@ -17,6 +17,7 @@
package org.apache.seata.saga.engine.pcext.utils;
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;
@@ -60,12 +61,14 @@ public class CompensationHolder {
*/
private Stack<StateInstance> stateStackNeedCompensation = new Stack<>();
+ private static final ResourceLock HOLDER_LOCK = new ResourceLock();
+
public static CompensationHolder getCurrent(ProcessContext context,
boolean forceCreate) {
CompensationHolder compensationholder =
(CompensationHolder)
context.getVariable(DomainConstants.VAR_NAME_CURRENT_COMPENSATION_HOLDER);
if (compensationholder == null && forceCreate) {
- synchronized (context) {
+ try (ResourceLock ignored = HOLDER_LOCK.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/EngineUtils.java
b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/EngineUtils.java
index be3a9ff783..6e319be3a6 100644
---
a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/EngineUtils.java
+++
b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/EngineUtils.java
@@ -16,6 +16,7 @@
*/
package org.apache.seata.saga.engine.pcext.utils;
+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.AsyncCallback;
@@ -45,6 +46,8 @@ public class EngineUtils {
private static final Logger LOGGER =
LoggerFactory.getLogger(EngineUtils.class);
+ private static final ResourceLock EXCEPTION_LOCK = new ResourceLock();
+
/**
* generate parent id
*
@@ -198,7 +201,7 @@ public class EngineUtils {
List<Class<? extends Exception>> exceptionClasses =
exceptionMatch.getExceptionClasses();
if (CollectionUtils.isNotEmpty(exceptions)) {
if (exceptionClasses == null) {
- synchronized (exceptionMatch) {
+ try (ResourceLock ignored = EXCEPTION_LOCK.obtain()) {
exceptionClasses =
exceptionMatch.getExceptionClasses();
if (exceptionClasses == 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 1335202641..0459ef47e2 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
@@ -16,6 +16,7 @@
*/
package org.apache.seata.saga.engine.pcext.utils;
+import org.apache.seata.common.lock.ResourceLock;
import org.apache.seata.saga.proctrl.ProcessContext;
import org.apache.seata.saga.statelang.domain.DomainConstants;
@@ -38,12 +39,14 @@ public class LoopContextHolder {
private final Stack<Integer> forwardCounterStack = new Stack<>();
private Collection collection;
+ private static final ResourceLock CONTEXT_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_LOCK.obtain()) {
loopContextHolder =
(LoopContextHolder)
context.getVariable(DomainConstants.VAR_NAME_CURRENT_LOOP_CONTEXT_HOLDER);
if (null == loopContextHolder) {
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 5208ad882c..a229fcd2c9 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
@@ -17,6 +17,7 @@
package org.apache.seata.saga.engine.pcext.utils;
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;
@@ -56,6 +57,8 @@ public class LoopTaskUtils {
public static final String LOOP_STATE_NAME_PATTERN = "-loop-";
+ private static final ResourceLock LOOP_LOCK = new ResourceLock();
+
/**
* get Loop Config from State
*
@@ -227,7 +230,7 @@ public class LoopTaskUtils {
currentLoopContext.getNrOfCompletedInstances().get();
if (!currentLoopContext.isCompletionConditionSatisfied()) {
- synchronized (currentLoopContext) {
+ try (ResourceLock ignored = LOOP_LOCK.obtain()) {
if (!currentLoopContext.isCompletionConditionSatisfied()) {
Map<String, Object> stateMachineContext =
(Map<String, Object>)
context.getVariable(DomainConstants.VAR_NAME_STATEMACHINE_CONTEXT);
diff --git
a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/ParameterUtils.java
b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/ParameterUtils.java
index 38f8204466..4c015827b1 100644
---
a/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/ParameterUtils.java
+++
b/saga/seata-saga-engine/src/main/java/org/apache/seata/saga/engine/pcext/utils/ParameterUtils.java
@@ -16,6 +16,7 @@
*/
package org.apache.seata.saga.engine.pcext.utils;
+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.expression.Expression;
@@ -36,6 +37,8 @@ import java.util.Map;
*/
public class ParameterUtils {
+ private static final ResourceLock INPUT_LOCK = new ResourceLock();
+
public static List<Object> createInputParams(
ExpressionResolver expressionResolver,
StateInstanceImpl stateInstance,
@@ -48,7 +51,7 @@ public class ParameterUtils {
List<Object> inputExpressions = serviceTaskState.getInputExpressions();
if (inputExpressions == null) {
- synchronized (serviceTaskState) {
+ try (ResourceLock ignored = INPUT_LOCK.obtain()) {
inputExpressions = serviceTaskState.getInputExpressions();
if (inputExpressions == null) {
inputExpressions = new
ArrayList<>(inputAssignments.size());
@@ -77,7 +80,7 @@ public class ParameterUtils {
Map<String, Object> outputExpressions =
serviceTaskState.getOutputExpressions();
if (outputExpressions == null) {
- synchronized (serviceTaskState) {
+ try (ResourceLock ignored = INPUT_LOCK.obtain()) {
outputExpressions = serviceTaskState.getOutputExpressions();
if (outputExpressions == null) {
outputExpressions = new
LinkedHashMap<>(outputAssignments.size());
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 6ffdd9b83e..86e0ff65c0 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
@@ -16,6 +16,7 @@
*/
package org.apache.seata.saga.engine.repo.impl;
+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;
@@ -44,6 +45,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class StateMachineRepositoryImpl implements StateMachineRepository {
private static final Logger LOGGER =
LoggerFactory.getLogger(StateMachineRepositoryImpl.class);
+ private final ResourceLock ITEM_LOCK = new ResourceLock();
private Map<
String
/** Name_Tenant **/
@@ -66,7 +68,7 @@ public class StateMachineRepositoryImpl implements
StateMachineRepository {
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_LOCK.obtain()) {
if (item.getValue() == null) {
StateMachine stateMachine =
stateLangStore.getStateMachineById(stateMachineId);
if (stateMachine != null) {
@@ -92,7 +94,7 @@ public class StateMachineRepositoryImpl implements
StateMachineRepository {
Item item = CollectionUtils.computeIfAbsent(
stateMachineMapByNameAndTenant, stateMachineName + "_" +
tenantId, key -> new Item());
if (item.getValue() == null && stateLangStore != null) {
- synchronized (item) {
+ try (ResourceLock ignored = ITEM_LOCK.obtain()) {
if (item.getValue() == null) {
StateMachine stateMachine =
stateLangStore.getLastVersionStateMachine(stateMachineName, tenantId);
if (stateMachine != null) {
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 2f6c6f15f9..0e88229ada 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
@@ -17,6 +17,7 @@
package org.apache.seata.saga.proctrl.eventing.impl;
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<ProcessContext> {
private static final String VAR_NAME_SYNC_EXE_STACK =
"_sync_execution_stack_";
+ private final ResourceLock CONTEXT_LOCK = new ResourceLock();
+
@Override
public boolean offer(ProcessContext context) throws FrameworkException {
List<EventConsumer> eventHandlers =
getEventConsumers(context.getClass());
@@ -49,7 +52,7 @@ public class DirectEventBus extends
AbstractEventBus<ProcessContext> {
boolean isFirstEvent = false;
Stack<ProcessContext> currentStack = (Stack<ProcessContext>)
context.getVariable(VAR_NAME_SYNC_EXE_STACK);
if (currentStack == null) {
- synchronized (context) {
+ try (ResourceLock ignored = CONTEXT_LOCK.obtain()) {
currentStack = (Stack<ProcessContext>)
context.getVariable(VAR_NAME_SYNC_EXE_STACK);
if (currentStack == null) {
currentStack = new Stack<>();
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 b97cb064bf..922345a344 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
@@ -19,6 +19,7 @@ package org.apache.seata.saga.engine.invoker.impl;
import org.apache.seata.common.exception.FrameworkErrorCode;
import org.apache.seata.common.json.JsonSerializer;
import org.apache.seata.common.json.JsonSerializerFactory;
+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;
@@ -53,6 +54,9 @@ public class SpringBeanServiceInvoker implements
ServiceInvoker, ApplicationCont
private static final Logger LOGGER =
LoggerFactory.getLogger(SpringBeanServiceInvoker.class);
+ private final ResourceLock METHOD_LOCK = new ResourceLock();
+ private final ResourceLock RETRY_LOCK = new ResourceLock();
+
private ApplicationContext applicationContext;
private ThreadPoolExecutor threadPoolExecutor;
private String sagaJsonParser;
@@ -105,7 +109,7 @@ public class SpringBeanServiceInvoker implements
ServiceInvoker, ApplicationCont
Method method = state.getMethod();
if (method == null) {
- synchronized (state) {
+ try (ResourceLock ignored = METHOD_LOCK.obtain()) {
method = state.getMethod();
if (method == null) {
method = findMethod(bean.getClass(),
state.getServiceMethod(), state.getParameterTypes());
@@ -196,7 +200,7 @@ public class SpringBeanServiceInvoker implements
ServiceInvoker, ApplicationCont
} else {
List<Class<? extends Exception>> exceptionClasses =
retryConfig.getExceptionClasses();
if (exceptionClasses == null) {
- synchronized (retryConfig) {
+ try (ResourceLock ignored = RETRY_LOCK.obtain()) {
exceptionClasses =
retryConfig.getExceptionClasses();
if (exceptionClasses == null) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]