diff --git a/at-sample/dubbo-samples-seata/README.md b/at-sample/dubbo-samples-seata/README.md
new file mode 100644
index 000000000..2a444f7e4
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/README.md
@@ -0,0 +1,137 @@
+
+在Dubbo中可以使用Seata来实现分布式事务功能
+
+## 开始之前
+Apache Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。
+在Dubbo中集成Seata实现分布式事务非常方便,只需简单几步即可完成,本文将带你快速体验。开始前,请先完成以下内容:
+- 请克隆[seata-samples](https://github.com/apache/incubator-seata-samples)至本地并导入到开发工具中,并找到/at-sample/dubbo-samples-seata子项目。
+- 请下载最新版的[seata-server二进制包](https://seata.apache.org/zh-cn/unversioned/download/seata-server)至本地。
+
+
+### 步骤 1:建立数据库并初始化相关测试数据
+- 本文将使用MySQL 5.7 (更多支持的数据库可在文末查看附录)。
+ 进入dubbo-samples-seata的script目录,找到dubbo_biz.sql和undo_log.sql两个数据库脚本文件,内容如下:
+
+undo_log.sql是Seata AT 模式需要 `UNDO_LOG` 表
+```sql
+-- for AT mode you must to init this sql for you business database. the seata server not need it.
+CREATE TABLE IF NOT EXISTS `undo_log`
+(
+ `branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
+ `xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',
+ `context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
+ `rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
+ `log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
+ `log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
+ `log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
+ UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
+ ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
+ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);
+
+```
+dubbo_biz.sql是示例业务表以及初始化数据
+
+```sql
+DROP TABLE IF EXISTS `stock_tbl`;
+CREATE TABLE `stock_tbl`
+(
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `commodity_code` varchar(255) DEFAULT NULL,
+ `count` int(11) DEFAULT 0,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY (`commodity_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+DROP TABLE IF EXISTS `order_tbl`;
+CREATE TABLE `order_tbl`
+(
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `user_id` varchar(255) DEFAULT NULL,
+ `commodity_code` varchar(255) DEFAULT NULL,
+ `count` int(11) DEFAULT 0,
+ `money` int(11) DEFAULT 0,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+DROP TABLE IF EXISTS `account_tbl`;
+CREATE TABLE `account_tbl`
+(
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `user_id` varchar(255) DEFAULT NULL,
+ `money` int(11) DEFAULT 0,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+---INITIALIZE THE ACCOUNT TABLE
+INSERT INTO account_tbl(`user_id`,`money`) VALUES('ACC_001','1000');
+---INITIALIZE THE STOCK TABLE
+INSERT INTO stock_tbl(`commodity_code`,`count`) VALUES('STOCK_001','100');
+
+```
+#### 请依次执行以下操作:
+* 1.1 创建seata数据库(实际业务场景中会使用不同的数据库,本文为了方便演示仅创建一个数据库,所有的表都在该数据库中创建)
+* 1.2 执行undo_log.sql表中的脚本完成AT模式所需的undo_log表创建
+* 1.3 执行dubbo_biz.sql表中的脚本完成示例业务表创建以及测试数据的初始化
+
+### 步骤 2:更新spring-boot应用配置中的数据库连接信息
+
+请将以下3个子模块的数据库连接信息更新为你的信息,其他配置无需更改,至此,客户端的配置已经完毕。
+
+* dubbo-samples-seata-account
+* dubbo-samples-seata-order
+* dubbo-samples-seata-stock
+```yaml
+url: jdbc:mysql://127.0.0.1:3306/seata?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useOldAliasMetadataBehavior=true
+username: root
+password: 123456
+```
+
+### 步骤 3:启动Seata-Server
+- 本文使用的是Seata-Server V2.0.0版本。
+
+请将下载的Seata-Server二进制包解压,并进入bin目录,然后执行以下命令即可启动Seata-Server。
+
+如果你是Mac OS 或者Linux操作系统,请执行:
+```
+./seata-server.sh
+```
+或者你是Windows操作系统,请执行:
+```
+./seata-server.bat
+```
+
+### 步骤 4:启动示例
+
+一切准备就绪,开始启动示例
+
+#### 请依次启动以下子项目:
+* 4.1 Account Service
+* 4.2 Order Service
+* 4.3 Stock Service
+* 4.4 Business Service
+
+### 步骤 5:查看分布式事务执行结果
+通过访问以下链接,可以测试分布式事务成功提交流程:
+
+http://127.0.0.1:9999/test/commit?userId=ACC_001&commodityCode=STOCK_001&orderCount=1
+
+**分布式事务成功提交时,业务表的数据将正常更新,请注意观察数据库表中的数据。**
+
+通过访问以下链接,可以测试分布式事务失败回滚流程:
+
+http://127.0.0.1:9999/test/rollback?userId=ACC_001&commodityCode=STOCK_001&orderCount=1
+
+**分布式事务失败回滚时,业务表的数据将没有任何改变,请注意观察数据库表中的数据。**
+
+### 附录
+* 支持的事务模式:Seata目前支持AT、TCC、SAGA、XA等模式,详情请访问[Seata官网](https://seata.apache.org/zh-cn/docs/user/mode/at)进行了解
+* 支持的配置中心:Seata支持丰富的配置中心,如zookeeper、nacos、consul、apollo、etcd、file(本文使用此配置中心,无需第三方依赖,方便快速演示),详情请访问[Seata配置中心](https://seata.apache.org/zh-cn/docs/user/configuration/)进行了解
+* 支持的注册中心:Seata支持丰富的注册中心,如eureka、sofa、redis、zookeeper、nacos、consul、etcd、file(本文使用此注册中心,无需第三方依赖,方便快速演示),详情请访问[Seata注册中心](https://seata.apache.org/zh-cn/docs/user/registry/)进行了解
+* 支持的部署方式:直接部署、Docker、K8S、Helm等部署方式,详情请访问[Seata部署方式](https://seata.apache.org/zh-cn/docs/ops/deploy-guide-beginner)进行了解
+* 支持的API:Seata的API分为两大类:High-Level API 和 Low-Level API,详情请访问[Seata API](https://seata.apache.org/zh-cn/docs/user/api)进行了解
+* 支持的数据库:Seata支持MySQL、Oracle、PostgreSQL、TiDB、MariaDB等数据库,不同的事务模式会有差别,详情请访问[Seata支持的数据库](https://seata.apache.org/zh-cn/docs/user/datasource)进行了解
+* 支持ORM框架:Seata 虽然是保证数据一致性的组件,但对于 ORM 框架并没有特殊的要求,像主流的Mybatis,Mybatis-Plus,Spring Data JPA, Hibernate等都支持。这是因为ORM框架位于JDBC结构的上层,而 Seata 的 AT,XA 事务模式是对 JDBC 标准接口操作的拦截和增强。详情请访问[Seata支持的ORM框架](https://seata.apache.org/zh-cn/docs/user/ormframework)进行了解
+* 支持的微服务框架:Seata目前支持Dubbo、gRPC、hsf、http、motan、sofa等框架,同时seata提供了丰富的拓展机制,理论上可以支持任何微服务框架。详情请访问[Seata支持的微服务框架](https://seata.apache.org/zh-cn/docs/user/microservice)进行了解
+* SQL限制:Seata 事务目前支持 INSERT、UPDATE、DELETE 三类 DML 语法的部分功能,这些类型都是已经经过Seata开源社区的验证。SQL 的支持范围还在不断扩大,建议在本文限制的范围内使用。详情请访问[Seata SQL限制](https://seata.apache.org/zh-cn/docs/user/sqlreference/sql-restrictions)进行了解
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/pom.xml b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/pom.xml
new file mode 100644
index 000000000..3d4f98cf2
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/pom.xml
@@ -0,0 +1,93 @@
+
+
+
+ 4.0.0
+
+ org.apache.dubbo
+ dubbo-samples-seata
+ 0.0.1-SNAPSHOT
+
+ dubbo-samples-seata-account
+ dubbo-samples-seata-account
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.apache.dubbo
+ dubbo-samples-seata-api
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.mysql
+ mysql-connector-j
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+ io.seata
+ seata-spring-boot-starter
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ org.apache.dubbo.samples.seata.account.AccountApplication
+
+
+
+ repackage
+
+ repackage
+
+
+
+
+
+
+
+
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/main/java/org/apache/dubbo/samples/seata/account/AccountApplication.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/main/java/org/apache/dubbo/samples/seata/account/AccountApplication.java
new file mode 100644
index 000000000..89f9d6c1f
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/main/java/org/apache/dubbo/samples/seata/account/AccountApplication.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.seata.account;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableDubbo
+public class AccountApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(AccountApplication.class, args);
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/main/java/org/apache/dubbo/samples/seata/account/service/AccountServiceImpl.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/main/java/org/apache/dubbo/samples/seata/account/service/AccountServiceImpl.java
new file mode 100644
index 000000000..f805bda71
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/main/java/org/apache/dubbo/samples/seata/account/service/AccountServiceImpl.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.dubbo.samples.seata.account.service;
+
+import io.seata.core.context.RootContext;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.dubbo.samples.seata.api.AccountService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@DubboService
+public class AccountServiceImpl implements AccountService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AccountService.class);
+
+ private final JdbcTemplate jdbcTemplate;
+
+ public AccountServiceImpl(JdbcTemplate jdbcTemplate) {
+ this.jdbcTemplate = jdbcTemplate;
+ }
+
+ @Override
+ public void debit(String userId, int money) {
+ LOGGER.info("Account Service ... xid: " + RootContext.getXID());
+ LOGGER.info("Deducting balance SQL: update account_tbl set money = money - {} where user_id = {}", money,
+ userId);
+
+ jdbcTemplate.update("update account_tbl set money = money - ? where user_id = ?", new Object[]{money, userId});
+ LOGGER.info("Account Service End ... ");
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/main/resources/application.yml b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/main/resources/application.yml
new file mode 100644
index 000000000..19b54ed1e
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/main/resources/application.yml
@@ -0,0 +1,53 @@
+# 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.
+spring:
+ application:
+ name: AccountApplication
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://${mysql.address:127.0.0.1}:${mysql.port:3306}/seata?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useOldAliasMetadataBehavior=true
+ username: root
+ password: helloworld
+ hikari:
+ connection-timeout: 30000
+ idle-timeout: 600000
+ max-lifetime: 1800000
+ maximum-pool-size: 100
+ minimum-idle: 10
+ pool-name: HikaraPool-1
+dubbo:
+ application:
+ logger: slf4j
+ name: ${spring.application.name}
+ qos-enable: false
+ registry:
+ address: multicast://224.5.6.7:1234
+ protocol:
+ port: 20881
+ name: dubbo
+seata:
+ enabled: true
+ application-id: dubbo-samples-seata
+ tx-service-group: default_tx_group
+ service:
+ vgroup-mapping:
+ default_tx_group: default
+ grouplist:
+ default: ${seata.address:127.0.0.1}:${seata.port:8091}
+ registry:
+ type: file
+ config:
+ type: file
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/test/java/org/apache/dubbo/samples/seata/AccountApplicationTests.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/test/java/org/apache/dubbo/samples/seata/AccountApplicationTests.java
new file mode 100644
index 000000000..081753578
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-account/src/test/java/org/apache/dubbo/samples/seata/AccountApplicationTests.java
@@ -0,0 +1,30 @@
+/*
+ * 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.dubbo.samples.seata;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class AccountApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/pom.xml b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/pom.xml
new file mode 100644
index 000000000..11eca3ad8
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/pom.xml
@@ -0,0 +1,34 @@
+
+
+
+ 4.0.0
+
+ org.apache.dubbo
+ dubbo-samples-seata
+ 0.0.1-SNAPSHOT
+
+ dubbo-samples-seata-api
+ dubbo-samples-seata-api
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/AccountService.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/AccountService.java
new file mode 100644
index 000000000..ed89fa4c1
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/AccountService.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.seata.api;
+
+/**
+ * The interface Account service.
+ */
+public interface AccountService {
+
+ /**
+ * debit
+ *
+ * @param userId
+ * @param money
+ */
+ void debit(String userId, int money);
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/BusinessService.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/BusinessService.java
new file mode 100644
index 000000000..6dd6cad2b
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/BusinessService.java
@@ -0,0 +1,43 @@
+/*
+ * 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.dubbo.samples.seata.api;
+
+/**
+ * The interface Business service.
+ */
+public interface BusinessService {
+
+ /**
+ * purchase commit
+ *
+ * @param userId
+ * @param commodityCode
+ * @param orderCount
+ */
+ void purchaseCommit(String userId, String commodityCode, int orderCount);
+
+
+ /**
+ * purchase rollback
+ *
+ * @param userId
+ * @param commodityCode
+ * @param orderCount
+ */
+ void purchaseRollback(String userId, String commodityCode, int orderCount);
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/Order.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/Order.java
new file mode 100644
index 000000000..161a11b65
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/Order.java
@@ -0,0 +1,52 @@
+/*
+ * 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.dubbo.samples.seata.api;
+
+import java.io.Serializable;
+
+/**
+ * The type Order.
+ */
+public class Order implements Serializable {
+ /**
+ * The Id.
+ */
+ public long id;
+ /**
+ * The User id.
+ */
+ public String userId;
+ /**
+ * The Commodity code.
+ */
+ public String commodityCode;
+ /**
+ * The Count.
+ */
+ public int count;
+ /**
+ * The Money.
+ */
+ public int money;
+
+ @Override
+ public String toString() {
+ return "Order{" + "id=" + id + ", userId='" + userId + '\'' + ", commodityCode='" + commodityCode + '\''
+ + ", count=" + count + ", money=" + money + '}';
+ }
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/OrderService.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/OrderService.java
new file mode 100644
index 000000000..cbc43d73b
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/OrderService.java
@@ -0,0 +1,34 @@
+/*
+ * 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.dubbo.samples.seata.api;
+
+/**
+ * The interface Order service.
+ */
+public interface OrderService {
+ /**
+ * create order
+ *
+ * @param userId
+ * @param commodityCode
+ * @param orderCount
+ * @return the created order
+ */
+ Order create(String userId, String commodityCode, int orderCount);
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/StockService.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/StockService.java
new file mode 100644
index 000000000..1233a3136
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-api/src/main/java/org/apache/dubbo/samples/seata/api/StockService.java
@@ -0,0 +1,40 @@
+/*
+ * 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.dubbo.samples.seata.api;
+
+/**
+ * The interface Stock service.
+ */
+public interface StockService {
+
+ /**
+ * deduct
+ *
+ * @param commodityCode
+ * @param count
+ */
+ void deduct(String commodityCode, int count);
+
+ /**
+ * batch deduct
+ *
+ * @param commodityCode
+ * @param count
+ */
+ void batchDeduct(String commodityCode, int count);
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/pom.xml b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/pom.xml
new file mode 100644
index 000000000..c0c9e9a45
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/pom.xml
@@ -0,0 +1,85 @@
+
+
+
+ 4.0.0
+
+ org.apache.dubbo
+ dubbo-samples-seata
+ 0.0.1-SNAPSHOT
+
+ dubbo-samples-seata-business
+ dubbo-samples-seata-business
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.apache.dubbo
+ dubbo-samples-seata-api
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.seata
+ seata-spring-boot-starter
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ org.apache.dubbo.samples.seata.business.BusinessApplication
+
+
+
+ repackage
+
+ repackage
+
+
+
+
+
+
+
+
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/java/org/apache/dubbo/samples/seata/business/BusinessApplication.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/java/org/apache/dubbo/samples/seata/business/BusinessApplication.java
new file mode 100644
index 000000000..ac14d94c3
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/java/org/apache/dubbo/samples/seata/business/BusinessApplication.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.seata.business;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableDubbo
+public class BusinessApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(BusinessApplication.class, args);
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/java/org/apache/dubbo/samples/seata/business/controller/TestController.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/java/org/apache/dubbo/samples/seata/business/controller/TestController.java
new file mode 100644
index 000000000..62f66a82f
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/java/org/apache/dubbo/samples/seata/business/controller/TestController.java
@@ -0,0 +1,50 @@
+/*
+ * 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.dubbo.samples.seata.business.controller;
+
+import org.apache.dubbo.samples.seata.api.BusinessService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/test")
+public class TestController {
+ private final BusinessService businessService;
+
+ public TestController(BusinessService businessService) {
+ this.businessService = businessService;
+ }
+
+ @GetMapping("/commit")
+ public String commit(@RequestParam String userId,@RequestParam String commodityCode,@RequestParam int orderCount){
+ this.businessService.purchaseCommit(userId,commodityCode,orderCount);
+ return "commit";
+ }
+
+ @GetMapping("/rollback")
+ public String rollback(@RequestParam String userId,@RequestParam String commodityCode,@RequestParam int orderCount){
+ try {
+ this.businessService.purchaseRollback(userId,commodityCode,orderCount);
+ return "commit";
+ }catch (Exception e){
+ return "rollback";
+ }
+ }
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/java/org/apache/dubbo/samples/seata/business/service/BusinessServiceImpl.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/java/org/apache/dubbo/samples/seata/business/service/BusinessServiceImpl.java
new file mode 100644
index 000000000..c57f5b46d
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/java/org/apache/dubbo/samples/seata/business/service/BusinessServiceImpl.java
@@ -0,0 +1,58 @@
+/*
+ * 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.dubbo.samples.seata.business.service;
+
+import io.seata.core.context.RootContext;
+import io.seata.spring.annotation.GlobalTransactional;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.samples.seata.api.BusinessService;
+import org.apache.dubbo.samples.seata.api.OrderService;
+import org.apache.dubbo.samples.seata.api.StockService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+@Service
+public class BusinessServiceImpl implements BusinessService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BusinessService.class);
+
+ @DubboReference(check = false)
+ private StockService stockService;
+ @DubboReference(check = false)
+ private OrderService orderService;
+
+ @Override
+ @GlobalTransactional(timeoutMills = 300000, name = "dubbo-samples-seata")
+ public void purchaseCommit(String userId, String commodityCode, int orderCount) {
+ LOGGER.info("purchase begin ... xid: " + RootContext.getXID());
+ stockService.deduct(commodityCode, orderCount);
+ orderService.create(userId, commodityCode, orderCount);
+ }
+
+ @Override
+ @GlobalTransactional(timeoutMills = 300000, name = "dubbo-samples-seata")
+ public void purchaseRollback(String userId, String commodityCode, int orderCount) {
+ LOGGER.info("purchase begin ... xid: " + RootContext.getXID());
+ stockService.deduct(commodityCode, orderCount);
+ orderService.create(userId, commodityCode, orderCount);
+ throw new RuntimeException("purchase rollback!");
+
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/resources/application.yml b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/resources/application.yml
new file mode 100644
index 000000000..d244dcdeb
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/main/resources/application.yml
@@ -0,0 +1,43 @@
+# 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.
+server:
+ port: 9999
+spring:
+ application:
+ name: BusinessApplication
+dubbo:
+ application:
+ logger: slf4j
+ name: ${spring.application.name}
+ qos-enable: false
+ registry:
+ address: multicast://224.5.6.7:1234
+ protocol:
+ port: 20882
+ name: dubbo
+seata:
+ enabled: true
+ application-id: dubbo-samples-seata
+ tx-service-group: default_tx_group
+ service:
+ vgroup-mapping:
+ default_tx_group: default
+ grouplist:
+ default: ${seata.address:127.0.0.1}:${seata.port:8091}
+ registry:
+ type: file
+ config:
+ type: file
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/test/java/org/apache/dubbo/samples/seata/business/BusinessApplicationIT.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/test/java/org/apache/dubbo/samples/seata/business/BusinessApplicationIT.java
new file mode 100644
index 000000000..a706519b2
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-business/src/test/java/org/apache/dubbo/samples/seata/business/BusinessApplicationIT.java
@@ -0,0 +1,42 @@
+/*
+ * 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.dubbo.samples.seata.business;
+
+import org.apache.dubbo.samples.seata.api.BusinessService;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+public class BusinessApplicationIT {
+
+ @Autowired
+ private BusinessService businessService;
+
+ @Test
+ void testRollback() {
+ Assertions.assertThrows(RuntimeException.class, () -> businessService.purchaseRollback("ACC_001", "STOCK_001", 1));
+ }
+
+ @Test
+ void testCommit() {
+ Assertions.assertDoesNotThrow(() -> businessService.purchaseCommit("ACC_001", "STOCK_001", 1));
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/pom.xml b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/pom.xml
new file mode 100644
index 000000000..3d929a9be
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/pom.xml
@@ -0,0 +1,93 @@
+
+
+
+ 4.0.0
+
+ org.apache.dubbo
+ dubbo-samples-seata
+ 0.0.1-SNAPSHOT
+
+ dubbo-samples-seata-order
+ dubbo-samples-seata-order
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.apache.dubbo
+ dubbo-samples-seata-api
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.mysql
+ mysql-connector-j
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+ io.seata
+ seata-spring-boot-starter
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ org.apache.dubbo.samples.seata.order.OrderApplication
+
+
+
+ repackage
+
+ repackage
+
+
+
+
+
+
+
+
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/main/java/org/apache/dubbo/samples/seata/order/OrderApplication.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/main/java/org/apache/dubbo/samples/seata/order/OrderApplication.java
new file mode 100644
index 000000000..df6ebff47
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/main/java/org/apache/dubbo/samples/seata/order/OrderApplication.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.seata.order;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableDubbo
+public class OrderApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(OrderApplication.class, args);
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/main/java/org/apache/dubbo/samples/seata/order/service/OrderServiceImpl.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/main/java/org/apache/dubbo/samples/seata/order/service/OrderServiceImpl.java
new file mode 100644
index 000000000..61b69e255
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/main/java/org/apache/dubbo/samples/seata/order/service/OrderServiceImpl.java
@@ -0,0 +1,99 @@
+/*
+ * 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.dubbo.samples.seata.order.service;
+
+import io.seata.core.context.RootContext;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.dubbo.samples.seata.api.AccountService;
+import org.apache.dubbo.samples.seata.api.Order;
+import org.apache.dubbo.samples.seata.api.OrderService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.PreparedStatementCreator;
+import org.springframework.jdbc.support.GeneratedKeyHolder;
+import org.springframework.jdbc.support.KeyHolder;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+@DubboService
+public class OrderServiceImpl implements OrderService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(OrderService.class);
+
+ @DubboReference(check = false)
+ private AccountService accountService;
+
+ private final JdbcTemplate jdbcTemplate;
+
+ public OrderServiceImpl(JdbcTemplate jdbcTemplate) {
+ this.jdbcTemplate = jdbcTemplate;
+ }
+
+ @Override
+ public Order create(String userId, String commodityCode, int orderCount) {
+ LOGGER.info("Order Service Begin ... xid: " + RootContext.getXID());
+
+ // 计算订单金额
+ int orderMoney = calculate(commodityCode, orderCount);
+
+ // 从账户余额扣款
+ accountService.debit(userId, orderMoney);
+
+ final Order order = new Order();
+ order.userId = userId;
+ order.commodityCode = commodityCode;
+ order.count = orderCount;
+ order.money = orderMoney;
+
+ KeyHolder keyHolder = new GeneratedKeyHolder();
+
+ LOGGER.info(
+ "Order Service SQL: insert into order_tbl (user_id, commodity_code, count, money) values ({}, {}, {}, {})",
+ userId, commodityCode, orderCount, orderMoney);
+
+ jdbcTemplate.update(new PreparedStatementCreator() {
+
+ @Override
+ public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
+ PreparedStatement pst = con.prepareStatement(
+ "insert into order_tbl (user_id, commodity_code, count, money) values (?, ?, ?, ?)",
+ PreparedStatement.RETURN_GENERATED_KEYS);
+ pst.setObject(1, order.userId);
+ pst.setObject(2, order.commodityCode);
+ pst.setObject(3, order.count);
+ pst.setObject(4, order.money);
+ return pst;
+ }
+ }, keyHolder);
+
+ order.id = keyHolder.getKey().longValue();
+
+ LOGGER.info("Order Service End ... Created " + order);
+
+ return order;
+ }
+
+ private int calculate(String commodityId, int orderCount) {
+ return 200 * orderCount;
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/main/resources/application.yml b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/main/resources/application.yml
new file mode 100644
index 000000000..519afebfc
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/main/resources/application.yml
@@ -0,0 +1,53 @@
+# 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.
+spring:
+ application:
+ name: OrderApplication
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://${mysql.address:127.0.0.1}:${mysql.port:3306}/seata?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useOldAliasMetadataBehavior=true
+ username: root
+ password: helloworld
+ hikari:
+ connection-timeout: 30000
+ idle-timeout: 600000
+ max-lifetime: 1800000
+ maximum-pool-size: 100
+ minimum-idle: 10
+ pool-name: HikaraPool-1
+dubbo:
+ application:
+ logger: slf4j
+ name: ${spring.application.name}
+ qos-enable: false
+ registry:
+ address: multicast://224.5.6.7:1234
+ protocol:
+ port: 20883
+ name: dubbo
+seata:
+ enabled: true
+ application-id: dubbo-samples-seata
+ tx-service-group: default_tx_group
+ service:
+ vgroup-mapping:
+ default_tx_group: default
+ grouplist:
+ default: ${seata.address:127.0.0.1}:${seata.port:8091}
+ registry:
+ type: file
+ config:
+ type: file
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/test/java/org/apache/dubbo/samples/seata/OrderApplicationTests.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/test/java/org/apache/dubbo/samples/seata/OrderApplicationTests.java
new file mode 100644
index 000000000..ff77b07f3
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-order/src/test/java/org/apache/dubbo/samples/seata/OrderApplicationTests.java
@@ -0,0 +1,30 @@
+/*
+ * 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.dubbo.samples.seata;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class OrderApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/pom.xml b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/pom.xml
new file mode 100644
index 000000000..37fe39bc8
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/pom.xml
@@ -0,0 +1,93 @@
+
+
+
+ 4.0.0
+
+ org.apache.dubbo
+ dubbo-samples-seata
+ 0.0.1-SNAPSHOT
+
+ dubbo-samples-seata-stock
+ dubbo-samples-seata-stock
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.apache.dubbo
+ dubbo-samples-seata-api
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.mysql
+ mysql-connector-j
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
+
+ io.seata
+ seata-spring-boot-starter
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ org.apache.dubbo.samples.seata.stock.StockApplication
+
+
+
+ repackage
+
+ repackage
+
+
+
+
+
+
+
+
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/main/java/org/apache/dubbo/samples/seata/stock/StockApplication.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/main/java/org/apache/dubbo/samples/seata/stock/StockApplication.java
new file mode 100644
index 000000000..02c7f0063
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/main/java/org/apache/dubbo/samples/seata/stock/StockApplication.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.seata.stock;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableDubbo
+public class StockApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(StockApplication.class, args);
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/main/java/org/apache/dubbo/samples/seata/stock/service/StockServiceImpl.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/main/java/org/apache/dubbo/samples/seata/stock/service/StockServiceImpl.java
new file mode 100644
index 000000000..126c735b0
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/main/java/org/apache/dubbo/samples/seata/stock/service/StockServiceImpl.java
@@ -0,0 +1,63 @@
+/*
+ * 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.dubbo.samples.seata.stock.service;
+
+import io.seata.core.context.RootContext;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.dubbo.samples.seata.api.StockService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@DubboService
+public class StockServiceImpl implements StockService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(StockService.class);
+
+ private final JdbcTemplate jdbcTemplate;
+
+ public StockServiceImpl(JdbcTemplate jdbcTemplate) {
+ this.jdbcTemplate = jdbcTemplate;
+ }
+
+ @Override
+ public void deduct(String commodityCode, int count) {
+ LOGGER.info("Stock Service Begin ... xid: " + RootContext.getXID());
+ LOGGER.info("Deducting inventory SQL: update stock_tbl set count = count - {} where commodity_code = {}", count,
+ commodityCode);
+
+ jdbcTemplate.update("update stock_tbl set count = count - ? where commodity_code = ?",
+ new Object[]{count, commodityCode});
+ LOGGER.info("Stock Service End ... ");
+
+ }
+
+ @Override
+ public void batchDeduct(String commodityCode, int count) {
+ LOGGER.info("Stock Service Begin ... xid: " + RootContext.getXID());
+ LOGGER.info("Deducting inventory SQL: update stock_tbl set count = count - {} where commodity_code = {}", count,
+ commodityCode);
+
+ jdbcTemplate.batchUpdate(
+ "update stock_tbl set count = count - " + count + " where commodity_code = '" + commodityCode + "'",
+ "update stock_tbl set count = count - " + count + " where commodity_code = '" + commodityCode + "'");
+ LOGGER.info("Stock Service End ... ");
+
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/main/resources/application.yml b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/main/resources/application.yml
new file mode 100644
index 000000000..617df9e8a
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/main/resources/application.yml
@@ -0,0 +1,53 @@
+# 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.
+spring:
+ application:
+ name: StockApplication
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://${mysql.address:127.0.0.1}:${mysql.port:3306}/seata?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useOldAliasMetadataBehavior=true
+ username: root
+ password: helloworld
+ hikari:
+ connection-timeout: 30000
+ idle-timeout: 600000
+ max-lifetime: 1800000
+ maximum-pool-size: 100
+ minimum-idle: 10
+ pool-name: HikaraPool-1
+dubbo:
+ application:
+ logger: slf4j
+ name: ${spring.application.name}
+ qos-enable: false
+ registry:
+ address: multicast://224.5.6.7:1234
+ protocol:
+ port: 20884
+ name: dubbo
+seata:
+ enabled: true
+ application-id: dubbo-samples-seata
+ tx-service-group: default_tx_group
+ service:
+ vgroup-mapping:
+ default_tx_group: default
+ grouplist:
+ default: ${seata.address:127.0.0.1}:${seata.port:8091}
+ registry:
+ type: file
+ config:
+ type: file
diff --git a/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/test/java/org/apache/dubbo/samples/seata/StockApplicationTests.java b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/test/java/org/apache/dubbo/samples/seata/StockApplicationTests.java
new file mode 100644
index 000000000..fda34638f
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/dubbo-samples-seata-stock/src/test/java/org/apache/dubbo/samples/seata/StockApplicationTests.java
@@ -0,0 +1,30 @@
+/*
+ * 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.dubbo.samples.seata;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class StockApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/at-sample/dubbo-samples-seata/pom.xml b/at-sample/dubbo-samples-seata/pom.xml
new file mode 100644
index 000000000..cab4df7b2
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/pom.xml
@@ -0,0 +1,94 @@
+
+
+
+ 4.0.0
+ org.apache.dubbo
+ dubbo-samples-seata
+ 0.0.1-SNAPSHOT
+ pom
+ dubbo-samples-seata
+ dubbo samples seata
+
+ 1.8
+ 1.8
+ UTF-8
+ UTF-8
+ 3.2.10
+ 2.7.10
+
+
+
+ dubbo-samples-seata-api
+ dubbo-samples-seata-account
+ dubbo-samples-seata-stock
+ dubbo-samples-seata-order
+ dubbo-samples-seata-business
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+ org.apache.dubbo
+ dubbo-bom
+ ${dubbo.version}
+ pom
+ import
+
+
+ org.apache.dubbo
+ dubbo-samples-seata-api
+ 0.0.1-SNAPSHOT
+
+
+ org.apache.dubbo
+ dubbo-samples-seata-account
+ 0.0.1-SNAPSHOT
+
+
+ org.apache.dubbo
+ dubbo-samples-seata-order
+ 0.0.1-SNAPSHOT
+
+
+ org.apache.dubbo
+ dubbo-samples-seata-stock
+ 0.0.1-SNAPSHOT
+
+
+ org.apache.dubbo
+ dubbo-samples-seata-business
+ 0.0.1-SNAPSHOT
+
+
+ io.seata
+ seata-spring-boot-starter
+ 2.0.0
+
+
+
+
+
+
diff --git a/at-sample/dubbo-samples-seata/script/db/dubbo_biz.sql b/at-sample/dubbo-samples-seata/script/db/dubbo_biz.sql
new file mode 100644
index 000000000..5ce0ffc83
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/script/db/dubbo_biz.sql
@@ -0,0 +1,51 @@
+--
+-- 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.
+--
+
+DROP TABLE IF EXISTS `stock_tbl`;
+CREATE TABLE `stock_tbl`
+(
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `commodity_code` varchar(255) DEFAULT NULL,
+ `count` int(11) DEFAULT 0,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY (`commodity_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+DROP TABLE IF EXISTS `order_tbl`;
+CREATE TABLE `order_tbl`
+(
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `user_id` varchar(255) DEFAULT NULL,
+ `commodity_code` varchar(255) DEFAULT NULL,
+ `count` int(11) DEFAULT 0,
+ `money` int(11) DEFAULT 0,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+DROP TABLE IF EXISTS `account_tbl`;
+CREATE TABLE `account_tbl`
+(
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `user_id` varchar(255) DEFAULT NULL,
+ `money` int(11) DEFAULT 0,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+INSERT INTO account_tbl(`user_id`,`money`) VALUES('ACC_001','1000');
+INSERT INTO stock_tbl(`commodity_code`,`count`) VALUES('STOCK_001','100');
diff --git a/at-sample/dubbo-samples-seata/script/db/undo_log.sql b/at-sample/dubbo-samples-seata/script/db/undo_log.sql
new file mode 100644
index 000000000..90435d295
--- /dev/null
+++ b/at-sample/dubbo-samples-seata/script/db/undo_log.sql
@@ -0,0 +1,29 @@
+--
+-- 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.
+--
+
+CREATE TABLE IF NOT EXISTS `undo_log`
+(
+ `branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
+ `xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',
+ `context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
+ `rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
+ `log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
+ `log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
+ `log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
+ UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
+ ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
+ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);