This is an automated email from the ASF dual-hosted git repository.
wangjian 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 630f502c8b feature: add SAGA_ANNOTATION mode to benchmark CLI (#8052)
630f502c8b is described below
commit 630f502c8b254c15eb175cf3995d47128d6bd554
Author: zihenzzz <[email protected]>
AuthorDate: Thu Apr 16 18:11:54 2026 +0800
feature: add SAGA_ANNOTATION mode to benchmark CLI (#8052)
---
changes/en-us/2.x.md | 1 +
changes/zh-cn/2.x.md | 1 +
test-suite/seata-benchmark-cli/README.md | 63 +++++++--
.../seata/benchmark/BenchmarkApplication.java | 2 +-
.../apache/seata/benchmark/BenchmarkRunner.java | 7 +-
.../seata/benchmark/config/BenchmarkConfig.java | 9 +-
.../executor/SagaAnnotationModeExecutor.java | 151 +++++++++++++++++++++
.../benchmark/saga/InventoryDbSagaService.java | 1 -
.../seata/benchmark/saga/OrderDbSagaService.java | 1 -
.../seata/benchmark/saga/PaymentDbSagaService.java | 1 -
.../seata/benchmark/saga/SagaDbEnvironment.java | 1 -
.../annotation/BenchmarkCompensatableService.java | 48 +++++++
.../BenchmarkCompensatableServiceImpl.java | 41 ++++++
13 files changed, 311 insertions(+), 16 deletions(-)
diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index 3fcbb47b13..87024bfdfd 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -19,6 +19,7 @@ Add changes here for all PR submitted to the 2.x branch.
<!-- Please add the `changes` to the following
location(feature/bugfix/optimize/test) based on the type of PR -->
### feature:
+- [[#8052](https://github.com/apache/incubator-seata/pull/8052)] add
SAGA_ANNOTATION mode to benchmark CLI
- [[#8014](https://github.com/apache/incubator-seata/pull/8014)] add P99.9
latency percentile to benchmark CLI
- [[#7882](https://github.com/apache/incubator-seata/pull/7882)] add metrics
for NamingServer
- [[#7760](https://github.com/apache/incubator-seata/pull/7760)] unify
Jackson/fastjson serialization
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 2f83fff256..7585a7b811 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -20,6 +20,7 @@
### feature:
+- [[#8052](https://github.com/apache/incubator-seata/pull/8052)] 为benchmark
CLI新增SAGA_ANNOTATION模式
- [[#7882](https://github.com/apache/incubator-seata/pull/7882)]
为NamingServer增加Metrics监控
- [[#7760](https://github.com/apache/incubator-seata/pull/7760)]
统一Jackson/fastjson序列化器
- [[#7000](https://github.com/apache/incubator-seata/pull/7000)]
支持多版本codec,修复不返回客户端注册失败消息的问题
diff --git a/test-suite/seata-benchmark-cli/README.md
b/test-suite/seata-benchmark-cli/README.md
index 49ac85fe9c..2e6d0b1180 100644
--- a/test-suite/seata-benchmark-cli/README.md
+++ b/test-suite/seata-benchmark-cli/README.md
@@ -20,7 +20,7 @@ A command-line benchmark tool for stress testing Seata
transaction modes.
## Features
-- Support for **AT**, **TCC**, and **SAGA** transaction modes
+- Support for **AT**, **TCC**, **SAGA**, and **SAGA_ANNOTATION** transaction
modes
- **Dual execution modes**:
- **Empty mode** (`--branches 0`): Pure Seata protocol overhead testing
- **Real mode** (`--branches N`): Actual distributed transaction execution
@@ -80,6 +80,13 @@ java -jar seata-benchmark-cli.jar \
--mode SAGA \
--tps 100 \
--duration 60
+
+# SAGA_ANNOTATION mode benchmark (empty transaction)
+java -jar seata-benchmark-cli.jar \
+ --server 127.0.0.1:8091 \
+ --mode SAGA_ANNOTATION \
+ --tps 100 \
+ --duration 60
```
### Real Mode (with actual database operations)
@@ -228,7 +235,7 @@ Usage: seata-benchmark [-hV]
[--application-id=<applicationId>]
Options:
-s, --server=<server> Seata Server address (host:port)
- -m, --mode=<mode> Transaction mode: AT, TCC, or SAGA
+ -m, --mode=<mode> Transaction mode: AT, TCC, SAGA, or
SAGA_ANNOTATION
-t, --tps=<targetTps> Target TPS (default: 100)
--threads=<threads> Concurrent threads (default: 10)
-d, --duration=<duration> Duration in seconds (default: 60)
@@ -467,6 +474,38 @@ java -jar seata-benchmark-cli.jar \
--saga-fail-step payment
```
+### Test SAGA_ANNOTATION Mode (Annotation-based Compensation)
+
+```bash
+# Empty mode: protocol overhead only
+java -jar seata-benchmark-cli.jar \
+ --server 127.0.0.1:8091 \
+ --mode SAGA_ANNOTATION \
+ --tps 100 \
+ --duration 60
+
+# Real mode: 3 branches per transaction, 5% compensation rate
+java -jar seata-benchmark-cli.jar \
+ --server 127.0.0.1:8091 \
+ --mode SAGA_ANNOTATION \
+ --tps 100 \
+ --duration 60 \
+ --branches 3 \
+ --rollback-percentage 5
+```
+
+### Compare SAGA vs SAGA_ANNOTATION
+
+```bash
+# State-machine Saga
+java -jar seata-benchmark-cli.jar --server 127.0.0.1:8091 \
+ --mode SAGA --tps 10000 --threads 50 --duration 60 --branches 3
+
+# Annotation-based Saga
+java -jar seata-benchmark-cli.jar --server 127.0.0.1:8091 \
+ --mode SAGA_ANNOTATION --tps 10000 --threads 50 --duration 60 --branches 3
+```
+
### Test TCC Mode at High Load
```bash
@@ -493,11 +532,12 @@ java -jar seata-benchmark-cli.jar \
### Transaction Modes
-| Mode | Empty Mode (branches=0) | Real Mode (branches>0) |
-|------|-------------------------|------------------------|
-| AT | Pure protocol overhead | MySQL via Testcontainers (account transfer)
|
-| TCC | Mock implementation | Mock implementation |
-| SAGA | Mock simulation | State machine engine with compensation |
+| Mode | Empty Mode (branches=0) | Real Mode (branches>0) |
+|------------------|-------------------------|------------------------|
+| AT | Pure protocol overhead | MySQL via Testcontainers
(account transfer) |
+| TCC | Mock implementation | Mock implementation |
+| SAGA | Mock simulation | State machine engine with
compensation |
+| SAGA_ANNOTATION | Pure protocol overhead | Annotation interceptor + TC
compensation callback |
### Empty Transaction Mode
@@ -506,6 +546,7 @@ For accurate benchmarking of Seata Server capacity, the
tool executes **empty tr
- **AT Mode**: Only `begin()` and `commit()` operations, no SQL execution
- **TCC Mode**: Empty transaction flow (mock implementation)
- **SAGA Mode**: Simplified simulation without state machine
+- **SAGA_ANNOTATION Mode**: Empty global transaction, no branch registration
This approach:
- Measures pure Seata protocol overhead
@@ -549,6 +590,12 @@ When `--branches` is set to a value greater than 0:
- Executes DB-backed order, inventory, and payment actions while still
supporting the same Saga shape, fail-step, random-seed, and timeout options
- Is intended for more realistic business-style Saga benchmarking
+- **SAGA_ANNOTATION Mode**:
+ - Uses `@SagaTransactional` + `@CompensationBusinessAction` annotation path
+ - Each branch is registered via the annotation interceptor (JDK dynamic
proxy, no Spring required)
+ - On rollback, the TC invokes the compensation method for every registered
branch
+ - `--branches N` = N `@CompensationBusinessAction` calls per transaction
+
### Fault Injection
Use `--rollback-percentage` to simulate transaction failures:
@@ -616,7 +663,7 @@ Logs are written to `seata-benchmark.log` in the current
directory.
## Roadmap
### Current Version (v1.0)
-- AT, TCC, and SAGA mode support
+- AT, TCC, SAGA, and SAGA_ANNOTATION mode support
- Empty and real transaction modes
- YAML configuration file support
- Fault injection (rollback percentage)
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/BenchmarkApplication.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/BenchmarkApplication.java
index 3d6987c2c4..189fdd8460 100644
---
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/BenchmarkApplication.java
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/BenchmarkApplication.java
@@ -45,7 +45,7 @@ public class BenchmarkApplication implements
Callable<Integer> {
@Option(
names = {"-m", "--mode"},
- description = "Transaction mode: AT, TCC, or SAGA",
+ description = "Transaction mode: AT, TCC, SAGA, or
SAGA_ANNOTATION",
required = false)
private String mode;
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/BenchmarkRunner.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/BenchmarkRunner.java
index da013e734f..3e5d00ec21 100644
---
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/BenchmarkRunner.java
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/BenchmarkRunner.java
@@ -18,6 +18,7 @@ package org.apache.seata.benchmark;
import org.apache.seata.benchmark.config.BenchmarkConfig;
import org.apache.seata.benchmark.executor.ATModeExecutor;
+import org.apache.seata.benchmark.executor.SagaAnnotationModeExecutor;
import org.apache.seata.benchmark.executor.SagaModeExecutor;
import org.apache.seata.benchmark.executor.TCCModeExecutor;
import org.apache.seata.benchmark.executor.TransactionExecutor;
@@ -132,9 +133,13 @@ public class BenchmarkRunner {
String sagaMode = isRealMode ? " (state machine engine)" : "
(empty transaction)";
System.out.println("Creating Saga mode executor" + sagaMode +
"\n");
return new SagaModeExecutor(config);
+ case SAGA_ANNOTATION:
+ String sagaAnnotationMode = isRealMode ? " (annotation-based
compensation)" : " (empty transaction)";
+ System.out.println("Creating SAGA_ANNOTATION mode executor" +
sagaAnnotationMode + "\n");
+ return new SagaAnnotationModeExecutor(config);
default:
throw new IllegalArgumentException(
- "Unsupported mode: " + branchType + ". Only AT, TCC,
and SAGA are supported.");
+ "Unsupported mode: " + branchType + ". Only AT, TCC,
SAGA, and SAGA_ANNOTATION are supported.");
}
}
}
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/config/BenchmarkConfig.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/config/BenchmarkConfig.java
index 3966bdbb69..20d34cd439 100644
---
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/config/BenchmarkConfig.java
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/config/BenchmarkConfig.java
@@ -19,6 +19,7 @@ package org.apache.seata.benchmark.config;
import org.apache.seata.benchmark.constant.BenchmarkConstants;
import org.apache.seata.core.model.BranchType;
+import java.util.EnumSet;
import java.util.Locale;
/**
@@ -194,9 +195,13 @@ public class BenchmarkConfig {
validateTpsAndThreads();
}
+ private static final EnumSet<BranchType> SUPPORTED_MODES =
+ EnumSet.of(BranchType.AT, BranchType.TCC, BranchType.SAGA,
BranchType.SAGA_ANNOTATION);
+
private void validateMode() {
- if (mode != BranchType.AT && mode != BranchType.TCC && mode !=
BranchType.SAGA) {
- throw new IllegalArgumentException("Unsupported mode: " + mode +
". Only AT, TCC, and SAGA are supported.");
+ if (!SUPPORTED_MODES.contains(mode)) {
+ throw new IllegalArgumentException(
+ "Unsupported mode: " + mode + ". Only AT, TCC, SAGA, and
SAGA_ANNOTATION are supported.");
}
}
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/executor/SagaAnnotationModeExecutor.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/executor/SagaAnnotationModeExecutor.java
new file mode 100644
index 0000000000..a8ec17e4f9
--- /dev/null
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/executor/SagaAnnotationModeExecutor.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.seata.benchmark.executor;
+
+import org.apache.seata.benchmark.config.BenchmarkConfig;
+import
org.apache.seata.benchmark.saga.annotation.BenchmarkCompensatableService;
+import
org.apache.seata.benchmark.saga.annotation.BenchmarkCompensatableServiceImpl;
+import org.apache.seata.integration.tx.api.interceptor.InvocationWrapper;
+import
org.apache.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
+import
org.apache.seata.saga.rm.interceptor.parser.SagaAnnotationActionInterceptorParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * SAGA_ANNOTATION mode transaction executor.
+ *
+ * <p>Supports two sub-modes controlled by {@code --branches}:
+ * <ul>
+ * <li><b>Empty mode</b> ({@code branches == 0}): starts and commits an
empty global transaction.
+ * Measures pure Seata protocol overhead with no branch
registration.</li>
+ * <li><b>Real mode</b> ({@code branches > 0}): registers {@code branches}
SAGA_ANNOTATION
+ * branches per transaction via the {@link
BenchmarkCompensatableService} proxy.
+ * On rollback the TC invokes the compensation method for every
registered branch.</li>
+ * </ul>
+ *
+ * <p>No Spring container is required. A JDK dynamic proxy wraps
+ * {@link
org.apache.seata.saga.rm.interceptor.SagaAnnotationActionInterceptorHandler},
+ * which is equivalent to what Spring AOP would produce at runtime.
+ * {@link org.apache.seata.saga.rm.SagaAnnotationResourceManager} is loaded
automatically
+ * via SPI when the {@code seata-saga-annotation} module is on the classpath.
+ */
+public class SagaAnnotationModeExecutor extends AbstractTransactionExecutor {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(SagaAnnotationModeExecutor.class);
+
+ private BenchmarkCompensatableService serviceProxy;
+ private BenchmarkCompensatableServiceImpl serviceImpl;
+
+ public SagaAnnotationModeExecutor(BenchmarkConfig config) {
+ super(config);
+ }
+
+ private boolean isRealMode() {
+ return config.getBranches() > 0;
+ }
+
+ @Override
+ public void init() {
+ if (isRealMode()) {
+ initRealMode();
+ } else {
+ LOGGER.info("SAGA_ANNOTATION mode executor initialized (empty
transaction mode)");
+ }
+ }
+
+ private void initRealMode() {
+ LOGGER.info("Initializing SAGA_ANNOTATION mode executor
(annotation-based compensation)");
+
+ serviceImpl = new BenchmarkCompensatableServiceImpl();
+
+ // SagaAnnotationActionInterceptorParser does two things:
+ // 1. Registers SagaAnnotationResource with DefaultResourceManager
(enables TC callbacks)
+ // 2. Returns a SagaAnnotationActionInterceptorHandler for proxy
dispatch
+ SagaAnnotationActionInterceptorParser parser = new
SagaAnnotationActionInterceptorParser();
+ ProxyInvocationHandler handler =
parser.parserInterfaceToProxy(serviceImpl, "benchmarkSagaAnnotationService");
+
+ // Wrap the handler with a JDK dynamic proxy — equivalent to Spring
AOP proxy
+ serviceProxy = (BenchmarkCompensatableService) Proxy.newProxyInstance(
+ BenchmarkCompensatableService.class.getClassLoader(),
+ new Class[] {BenchmarkCompensatableService.class},
+ (proxy, method, args) -> handler.invoke(new
InvocationWrapper() {
+ @Override
+ public Method getMethod() {
+ return method;
+ }
+
+ @Override
+ public Object getProxy() {
+ return proxy;
+ }
+
+ @Override
+ public Object getTarget() {
+ return serviceImpl;
+ }
+
+ @Override
+ public Object[] getArguments() {
+ return args;
+ }
+
+ @Override
+ public Object proceed() throws Throwable {
+ return method.invoke(serviceImpl, args);
+ }
+ }));
+
+ LOGGER.info("SAGA_ANNOTATION mode executor initialized ({} branches
per transaction)", config.getBranches());
+ }
+
+ @Override
+ protected void executeBusinessLogic() throws Exception {
+ if (!isRealMode()) {
+ return;
+ }
+ // Each proxy call triggers the annotation interceptor which registers
+ // one SAGA_ANNOTATION branch with the TC.
+ for (int i = 0; i < config.getBranches(); i++) {
+ serviceProxy.execute(null);
+ }
+ }
+
+ @Override
+ protected String getTransactionName() {
+ return "benchmark-saga-annotation-tx";
+ }
+
+ @Override
+ protected int getBranchCount() {
+ return config.getBranches();
+ }
+
+ @Override
+ protected Logger getLogger() {
+ return LOGGER;
+ }
+
+ @Override
+ public void destroy() {
+ serviceProxy = null;
+ serviceImpl = null;
+ LOGGER.info("SAGA_ANNOTATION mode executor destroyed");
+ }
+}
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/InventoryDbSagaService.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/InventoryDbSagaService.java
index cbdc66d39d..0af1ee14aa 100644
---
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/InventoryDbSagaService.java
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/InventoryDbSagaService.java
@@ -30,7 +30,6 @@ import java.util.concurrent.ThreadLocalRandom;
/**
* Database-backed inventory service for Saga benchmark.
- * @author zihenzzz
*/
public class InventoryDbSagaService {
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/OrderDbSagaService.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/OrderDbSagaService.java
index 4d4715e695..a78ea32872 100644
---
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/OrderDbSagaService.java
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/OrderDbSagaService.java
@@ -29,7 +29,6 @@ import java.util.concurrent.ThreadLocalRandom;
/**
* Database-backed order service for Saga benchmark.
- * @author zihenzzz
*/
public class OrderDbSagaService {
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/PaymentDbSagaService.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/PaymentDbSagaService.java
index 8428eae01f..08546249c5 100644
---
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/PaymentDbSagaService.java
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/PaymentDbSagaService.java
@@ -28,7 +28,6 @@ import java.util.concurrent.ThreadLocalRandom;
/**
* Database-backed payment service for Saga benchmark.
- * @author zihenzzz
*/
public class PaymentDbSagaService {
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/SagaDbEnvironment.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/SagaDbEnvironment.java
index 1b3435eba6..da3f42ae42 100644
---
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/SagaDbEnvironment.java
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/SagaDbEnvironment.java
@@ -34,7 +34,6 @@ import java.sql.Statement;
/**
* Database-backed environment for Saga benchmark business actions.
- * @author zihenzzz
*/
public class SagaDbEnvironment {
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/annotation/BenchmarkCompensatableService.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/annotation/BenchmarkCompensatableService.java
new file mode 100644
index 0000000000..c126ee7a26
--- /dev/null
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/annotation/BenchmarkCompensatableService.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.seata.benchmark.saga.annotation;
+
+import org.apache.seata.rm.tcc.api.BusinessActionContext;
+import org.apache.seata.saga.rm.api.CompensationBusinessAction;
+import org.apache.seata.saga.rm.api.SagaTransactional;
+
+/**
+ * Benchmark service interface for SAGA_ANNOTATION mode.
+ *
+ * <p>Each call to {@link #execute} registers one SAGA_ANNOTATION branch with
the TC.
+ * When the global transaction rolls back, the TC invokes {@link #compensate}
for every registered branch.
+ */
+@SagaTransactional
+public interface BenchmarkCompensatableService {
+
+ /**
+ * Forward action: registers a SAGA_ANNOTATION branch with the TC via the
annotation interceptor.
+ *
+ * @param context business action context injected by Seata
+ * @return true on success
+ */
+ @CompensationBusinessAction(name = "benchmarkSagaAnnotationAction",
compensationMethod = "compensate")
+ boolean execute(BusinessActionContext context);
+
+ /**
+ * Compensation action: called by the TC for each registered branch on
rollback.
+ *
+ * @param context business action context supplied by the TC
+ * @return true when compensation succeeds
+ */
+ boolean compensate(BusinessActionContext context);
+}
diff --git
a/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/annotation/BenchmarkCompensatableServiceImpl.java
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/annotation/BenchmarkCompensatableServiceImpl.java
new file mode 100644
index 0000000000..3743e56687
--- /dev/null
+++
b/test-suite/seata-benchmark-cli/src/main/java/org/apache/seata/benchmark/saga/annotation/BenchmarkCompensatableServiceImpl.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.seata.benchmark.saga.annotation;
+
+import org.apache.seata.rm.tcc.api.BusinessActionContext;
+
+/**
+ * Benchmark implementation of {@link BenchmarkCompensatableService}.
+ *
+ * <p>Both the forward action and the compensation are no-ops so that benchmark
+ * results reflect pure Seata SAGA_ANNOTATION protocol overhead rather than
+ * any application-level business logic cost.
+ */
+public class BenchmarkCompensatableServiceImpl implements
BenchmarkCompensatableService {
+
+ @Override
+ public boolean execute(BusinessActionContext context) {
+ // No-op: measures annotation interceptor + TC branch-registration
overhead only
+ return true;
+ }
+
+ @Override
+ public boolean compensate(BusinessActionContext context) {
+ // No-op: measures TC compensation-callback overhead only
+ return true;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]