案例源码使用SpringBoot 2.3.2 + Dubbo 2.7.6 + Mybatis 1.3.2 + Nacos 1.3.2 + Seata 1.3.0整合来实现Dubbo分布式事务管理,使用Nacos 作为 Dubbo和Seata的注册中心和配置中心,使用 MySQL 数据库和 MyBatis来操作数据库。
案例说明
项目包含四个模块,consumer模块依赖其他三个模块。
示例采用TCC模式与AT模式混合使用模式,所以兼容纯数据库事务和其他事务的支持。
建立数据库
要求:示例使用MySQL数据库,需要具有InnoDB引擎的MySQL。
注意: 实际上,在示例用例中,这3个服务应该有3个数据库。 但是,为了简单起见,我们只创建一个数据库并配置3个数据源,创建一个数据库seata。
创建回滚日志表
SEATA 的AT 模式需要 UNDO_LOG 表,用于支持回滚操作。
--注意此处0.3.0+增加唯一索引ux_undo_log
CREATE TABLE`undo_log` (
`id`bigint(20) NOT NULLAUTO_INCREMENT,
`branch_id`bigint(20) NOT NULL,
`xid`varchar(100) NOT NULL,
`context`varchar(128) NOT NULL,
`rollback_info` longblobNOT NULL,
`log_status`int(11) NOT NULL,
`log_created`datetime NOT NULL,
`log_modified`datetime NOT NULL,
`ext`varchar(100) DEFAULT NULL,PRIMARY KEY(`id`),UNIQUE KEY`ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
创建业务相关表
在action-db-provider项目的sql目录下也可以找到SQL脚本。
CREATE TABLE`t_user` (
`id`bigint(32) NOT NULLAUTO_INCREMENT,
`userName`varchar(32) NOT NULL,
`passWord`varchar(50) NOT NULL,
`realName`varchar(32) DEFAULT NULL,PRIMARY KEY(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
Nacos服务器
示例使用Nacos注册中心,需要先安装Nacos服务器。
下载软件
从下载地址下载服务器软件包,示例要求使用1.3.2版本,解压缩后启动。
运行模式
单机模式
因为下载下来的Nacos的启动脚本默认是使用集群模式启动的,需要依赖MySQL数据库,如果想使用单机模式,修改bin目录下的startup.cmd,设置其启动模式为单机模式。
集群模式
1. 将nacos/conf/nacos-mysql.sql导入自己的数据库
2. 配置修改nacos/conf/application.properties
spring.datasource.platform=mysql
db.num=1db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
启动服务
启动脚本在bin目录下,进入目录,执行脚本启动服务。
Windows:cmd> startup.cmd
Linux/Mac:bash> startup.sh -m standalone
关闭服务:
Windows:cmd> shutdown.cmd
Linux/Mac:bash> shutdown.sh
访问地址
登陆账号和密码都是 nacos,登陆成功的画面如下:
参考资料
Seata服务器
下载软件
从下载地址下载服务器软件包,这里下载1.3.0版本。
可以直接下载二进制软件包,也可以下载源码编译。
源码编译命令如下:
mvn -Prelease-all -DskipTests clean install –U
Seata配置
在seata的目录下需要关注两个配置文件。
首先是registry.conf,选择seata使用的注册中心,可选项包含file 、nacos 、eureka、redis、zk、consul、etcd3、sofa,默认配置是nacos。如果你的nacos地址账号等信息与默认配置不一致,将配置改成你自己的。
另外file.conf配置了seata的存储模式,seata的存储模式包括:file、db、redis,db、redis模式需要将连接信息配置成你自己的。
导入配置
如果下载的是二进制安装包,以下文件需要到git仓库源码或下载源码包获取。使用db模式导入配置,进入源码目录,mysql.sql为seata库必须的表,执行sql即可。
复制config.txt文件到seata根目录。
复制nacos中的nacos-config.sh、nacos-config.py到seata的conf目录。
然后命令行执行 sh nacos-config.sh hostip 导入配置到Nacos即可,导入完成之后,可以登录Nacos查看配置。
启动服务
启动脚本在bin目录下,进入目录,执行脚本启动服务。
Windows:cmd> seata-server.bat
Linux/Mac:bash> seata-server.sh
启动时可以指定包括主机、端口、日志存储模式等启动参数。
参数说明:
--host, -h
The host to bind,Default: 0.0.0.0
--port, -p
The port to listen,Default: 8091
--storeMode, -m
log store mode : file、db Default: file
--help
比如:
sh seata-server.sh -p 8091 -h 127.0.0.1 -m file
参考资料
搭建源码项目
项目结构
项目结构如下,项目包含四个模块,consumer模块依赖其他三个模块。
springboot-dubbo-seata-tccat
项目父模块,包含四个子模块,并提供了nacos、seata、dubbo的依赖。
service-consumer
提供分布式事务的服务和测试接口,通过RPC调用其他几个子模块的服务。
在TccController里提供了测试提交和回滚的相关接口,代码如下:
/*** 发起事务控制器
*
*@authorlouis*/@RestControllerpublic classTccController {
@ResourceprivateTccTransactionService tccTransactionService;/*** 分布式事务提交示例接口*/@GetMapping("/testCommit")publicString testCommit() {
String result=tccTransactionService.testCommit();return "----------test transaction commit---------- \n" +result;
}/*** 分布式事务回滚示例接口*/@GetMapping("/testRollback")publicString testRollback() {
String result= "";try{
tccTransactionService.testRollback();
}catch(Throwable t) {
result=t.getMessage();
}return "----------test transaction rollback ---------- \n" +result;
}
}
具体的的分布式服务在TccTransactionService中实现,方法内容如下:
@Servicepublic classTccTransactionService {
@ResourceprivateTccActionOne tccActionOne;
@ResourceprivateTccActionTwo tccActionTwo;
@Reference(version= "1.0.0", group = "tcc")privateUserService userService;/*** 测试分布式事务提交示例*/@GlobalTransactionalpublicString testCommit() {//第一个TCC 事务参与者String result= tccActionOne.prepare("action-one-commit").getMessage();//第二个TCC 事务参与者result= result + "\n" + tccActionTwo.prepare("action-two-commit").getMessage();//数据库操作userService.save(getUser());returnresult;
}/*** 测试分布式事务回滚示例*/@GlobalTransactionalpublicString testRollback() {//第一个TCC 事务参与者String result= tccActionOne.prepare("action-one-rollback").getMessage();//第二个TCC 事务参与者result= result + "\n" + tccActionTwo.prepare("action-two-rollback").getMessage();//数据库操作userService.save(getUser());throw newRuntimeException(result);
}
}
相关配置查看application.yml配置文件。
seata:
application-id: ${spring.application.name}
tx-service-group: my_test_tx_group # 事务分组,与seata-server配置保持一致
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace:
cluster: default
config:
type: nacos
nacos:
namespace:
server-addr: 127.0.0.1:8848
action-one-provider
提供TCC参与者,编写prepare、commit、rollback三个方法。
@Component
@Service(version= "1.0.0", group = "tcc")public class ActionOneServiceImpl implementsActionOneService {
@OverridepublicString prepare(String param) {
String result= ":::: action-one-provider prepare, rpc called success, param:" + param + ".";
System.out.println(result);returnresult;
}
@OverridepublicString commit(String param) {
String result= ":::: action-one-provider commit, rpc called success, param:" + param + ".";
System.out.println(result);returnresult;
}
@OverridepublicString rollback(String param) {
String result= ":::: action-one-provider rollback, rpc called success, param:" + param + ".";
System.out.println(result);returnresult;
}
}
action-two-provider
同actiono-one-provider一样,提供TCC参与者,编写prepare、commit、rollback三个方法。
action-db-provider
提供数据库操作服务,用于测试AT模式。
POM文件添加了Mybatis和MySQL的支持。
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
mysql
mysql-connector-java
UserServiceImpl提供了用户表相关的CRUD服务。
@Component
@Service(version= "1.0.0", group = "tcc")public class UserServiceImpl implementsUserService {
@ResourceprivateUserMapper userMapper;
@OverridepublicUser save(User user) {if(user.getId() == null || "".equals(user.getId())) {
userMapper.insert(user);
}else{
userMapper.updateByPrimaryKeySelective(user);
}returnuser;
}
...
}
运行示例程序
启动服务
直接运行各个模块的Application启动应用即可。
测试服务
成功案例
测试一下接口,观察控制台输出和数据库记录。
测试接口:
回滚案例
测试一下接口,观察控制台输出和数据库记录。
测试接口:
源码下载