当前位置:   article > 正文

分布式事务:SpringBoot+Dubbo+Seata+Nacos 实现案例

springboot+dubbo+nacos+seate

案例源码使用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

  1. CREATE TABLE `undo_log` (
  2. `id` bigint(20) NOT NULL AUTO_INCREMENT,
  3. `branch_id` bigint(20) NOT NULL,
  4. `xid` varchar(100) NOT NULL,
  5. `context` varchar(128) NOT NULL,
  6. `rollback_info` longblob NOT NULL,
  7. `log_status` int(11) NOT NULL,
  8. `log_created` datetime NOT NULL,
  9. `log_modified` datetime NOT NULL,
  10. `ext` varchar(100) DEFAULT NULL,
  11. PRIMARY KEY (`id`),
  12. UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
  13. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
创建业务相关表

在action-db-provider项目的sql目录下也可以找到SQL脚本。

  1. CREATE TABLE `t_user` (
  2. `id`bigint(32) NOT NULL AUTO_INCREMENT,
  3. `userName`varchar(32) NOT NULL,
  4. `passWord`varchar(50) NOT NULL,
  5. `realName`varchar(32) DEFAULT NULL,
  6. PRIMARY KEY (`id`)
  7. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

Nacos服务器

示例使用Nacos注册中心,需要先安装Nacos服务器。

下载软件

下载地址:https://github.com/alibaba/nacos/releases

从下载地址下载服务器软件包,示例要求使用1.3.2版本,解压缩后启动。

运行模式
单机模式

因为下载下来的Nacos的启动脚本默认是使用集群模式启动的,需要依赖MySQL数据库,如果想使用单机模式,修改bin目录下的startup.cmd,设置其启动模式为单机模式。

集群模式

1. 将nacos/conf/nacos-mysql.sql导入自己的数据库

2. 配置修改nacos/conf/application.properties

  1. spring.datasource.platform=mysql
  2. db.num=1
  3. db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
  4. db.user=root
  5. 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服务默认端口是8848 浏览器输入:http://127.0.0.1:8848/nacos

登陆账号和密码都是 nacos,登陆成功的画面如下:

 

参考资料

官方网站:https://nacos.io/zh-cn/

官方文档:https://nacos.io/zh-cn/docs/quick-start.html

Seata服务器

下载软件

下载地址: https://github.com/seata/seata/releases

从下载地址下载服务器软件包,这里下载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

参考资料

官方网站:https://seata.io/zh-cn/index.html

官方文档:https://seata.io/zh-cn/docs/overview/what-is-seata.html

搭建源码项目

项目结构

项目结构如下,项目包含四个模块,consumer模块依赖其他三个模块。

 

springboot-dubbo-seata-tccat

项目父模块,包含四个子模块,并提供了nacos、seata、dubbo的依赖。

 

service-consumer

提供分布式事务的服务和测试接口,通过RPC调用其他几个子模块的服务。

在TccController里提供了测试提交和回滚的相关接口,代码如下:

  1. /**
  2. * 发起事务控制器
  3. *
  4. * @author louis
  5. */
  6. @RestController
  7. public class TccController {
  8. @Resource
  9. private TccTransactionService tccTransactionService;
  10. /**
  11. * 分布式事务提交示例接口
  12. */
  13. @GetMapping("/testCommit")
  14. public String testCommit() {
  15. String result = tccTransactionService.testCommit();
  16. return "----------test transaction commit---------- \n" + result;
  17. }
  18. /**
  19. * 分布式事务回滚示例接口
  20. */
  21. @GetMapping("/testRollback")
  22. public String testRollback() {
  23. String result = "";
  24. try {
  25. tccTransactionService.testRollback();
  26. } catch (Throwable t) {
  27. result = t.getMessage();
  28. }
  29. return "----------test transaction rollback ---------- \n" + result;
  30. }
  31. }

具体的的分布式服务在TccTransactionService中实现,方法内容如下:

  1. @Service
  2. public class TccTransactionService {
  3. @Resource
  4. private TccActionOne tccActionOne;
  5. @Resource
  6. private TccActionTwo tccActionTwo;
  7. @Reference(version = "1.0.0", group = "tcc")
  8. private UserService userService;
  9. /**
  10. * 测试分布式事务提交示例
  11. */
  12. @GlobalTransactional
  13. public String testCommit() {
  14. // 第一个TCC 事务参与者
  15. String result = tccActionOne.prepare("action-one-commit").getMessage();
  16. // 第二个TCC 事务参与者
  17. result = result + "\n" + tccActionTwo.prepare("action-two-commit").getMessage();
  18. // 数据库操作
  19. userService.save(getUser());
  20. return result;
  21. }
  22. /**
  23. * 测试分布式事务回滚示例
  24. */
  25. @GlobalTransactional
  26. public String testRollback() {
  27. //第一个TCC 事务参与者
  28. String result = tccActionOne.prepare("action-one-rollback").getMessage();
  29. // 第二个TCC 事务参与者
  30. result = result + "\n" + tccActionTwo.prepare("action-two-rollback").getMessage();
  31. // 数据库操作
  32. userService.save(getUser());
  33. throw new RuntimeException(result);
  34. }
  35. }

相关配置查看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三个方法。

  1. @Component
  2. @Service(version = "1.0.0", group = "tcc")
  3. public class ActionOneServiceImpl implements ActionOneService {
  4. @Override
  5. public String prepare(String param) {
  6. String result = ":::: action-one-provider prepare, rpc called success, param:" + param + ".";
  7. System.out.println(result);
  8. return result;
  9. }
  10. @Override
  11. public String commit(String param) {
  12. String result = ":::: action-one-provider commit, rpc called success, param:" + param + ".";
  13. System.out.println(result);
  14. return result;
  15. }
  16. @Override
  17. public String rollback(String param) {
  18. String result = ":::: action-one-provider rollback, rpc called success, param:" + param + ".";
  19. System.out.println(result);
  20. return result;
  21. }
  22. }
action-two-provider

同actiono-one-provider一样,提供TCC参与者,编写prepare、commit、rollback三个方法。

action-db-provider

提供数据库操作服务,用于测试AT模式。

POM文件添加了Mybatis和MySQL的支持。

  1. <dependency>
  2. <groupId>org.mybatis.spring.boot</groupId>
  3. <artifactId>mybatis-spring-boot-starter</artifactId>
  4. <version>1.3.2</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>mysql</groupId>
  8. <artifactId>mysql-connector-java</artifactId>
  9. </dependency>

UserServiceImpl提供了用户表相关的CRUD服务。

  1. @Component
  2. @Service(version = "1.0.0", group = "tcc")
  3. public class UserServiceImpl implements UserService {
  4. @Resource
  5. private UserMapper userMapper;
  6. @Override
  7. public User save(User user) {
  8. if(user.getId() == null || "".equals(user.getId())) {
  9. userMapper.insert(user);
  10. } else {
  11. userMapper.updateByPrimaryKeySelective(user);
  12. }
  13. return user;
  14. }
  15. ...
  16. }

运行示例程序

启动服务

直接运行各个模块的Application启动应用即可。

 

测试服务
成功案例

测试一下接口,观察控制台输出和数据库记录。

测试接口:

http://localhost:8005/testCommit

回滚案例

测试一下接口,观察控制台输出和数据库记录。

测试接口:

http://localhost:8005/testRollback

源码下载

码云:https://gitee.com/liuge1988/seata-demo.git


作者:朝雨忆轻尘
出处:https://www.cnblogs.com/xifengxiaoma/ 
版权所有,欢迎转载,转载请注明原文作者及出处。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/165647
推荐阅读
相关标签
  

闽ICP备14008679号