Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dubbo-samples-seata #650

Merged
merged 1 commit into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions at-sample/dubbo-samples-seata/README.md
Original file line number Diff line number Diff line change
@@ -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)进行了解
93 changes: 93 additions & 0 deletions at-sample/dubbo-samples-seata/dubbo-samples-seata-account/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-samples-seata</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dubbo-samples-seata-account</artifactId>
<name>dubbo-samples-seata-account</name>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-samples-seata-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>org.apache.dubbo.samples.seata.account.AccountApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
@@ -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 ... ");
}

}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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() {
}

}
Loading
Loading