Ruoyi-Cloud集成Seata2.0实现分布式事务

前言

在网络上,关于Spring Cloud和Ruoyi-Cloud整合Seata的教程有很多,针对不同版本的 Seata 也有不少相关教程。
事实上,无论是 Spring Cloud 还是 Ruoyi-Cloud,其整合 Seata 的原理基本相同。这篇博文将详细介绍如何在本地开发环境下,在 Ruoyi-Cloud 中实现 Seata 2.0 的整合,希望能为大家在分布式项目中实现 Seata 的整合提供实用的帮助,提供一个清晰的操作思路。


一. 环境准备

  1. Nacos:https://nacos.io/download/nacos-server/
  2. Seata[v2.0]https://seata.apache.org/zh-cn/unversioned/download/seata-server
  3. Ruoyi-Cloud:https://gitee.com/y_project/RuoYi-Cloud

二、操作流程

1.并将项目配置项导入nacos中

在这里插入图片描述


2.导入所需要的数据库


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for branch_table
-- ----------------------------
DROP TABLE IF EXISTS `branch_table`;
CREATE TABLE `branch_table`  (
  `branch_id` bigint NOT NULL,
  `xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `transaction_id` bigint NULL DEFAULT NULL,
  `resource_group_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `resource_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `branch_type` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `status` tinyint NULL DEFAULT NULL,
  `client_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `application_data` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `gmt_create` datetime(6) NULL DEFAULT NULL,
  `gmt_modified` datetime(6) NULL DEFAULT NULL,
  PRIMARY KEY (`branch_id`) USING BTREE,
  INDEX `idx_xid`(`xid` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of branch_table
-- ----------------------------

-- ----------------------------
-- Table structure for distributed_lock
-- ----------------------------
DROP TABLE IF EXISTS `distributed_lock`;
CREATE TABLE `distributed_lock`  (
  `lock_key` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `lock_value` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `expire` bigint NULL DEFAULT NULL,
  PRIMARY KEY (`lock_key`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of distributed_lock
-- ----------------------------
INSERT INTO `distributed_lock` VALUES ('AsyncCommitting', ' ', 0);
INSERT INTO `distributed_lock` VALUES ('RetryCommitting', ' ', 0);
INSERT INTO `distributed_lock` VALUES ('RetryRollbacking', ' ', 0);
INSERT INTO `distributed_lock` VALUES ('TxTimeoutCheck', ' ', 0);

-- ----------------------------
-- Table structure for global_table
-- ----------------------------
DROP TABLE IF EXISTS `global_table`;
CREATE TABLE `global_table`  (
  `xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `transaction_id` bigint NULL DEFAULT NULL,
  `status` tinyint NOT NULL,
  `application_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `transaction_service_group` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `transaction_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `timeout` int NULL DEFAULT NULL,
  `begin_time` bigint NULL DEFAULT NULL,
  `application_data` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `gmt_create` datetime NULL DEFAULT NULL,
  `gmt_modified` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`xid`) USING BTREE,
  INDEX `idx_status_gmt_modified`(`status` ASC, `gmt_modified` ASC) USING BTREE,
  INDEX `idx_transaction_id`(`transaction_id` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of global_table
-- ----------------------------

-- ----------------------------
-- Table structure for lock_table
-- ----------------------------
DROP TABLE IF EXISTS `lock_table`;
CREATE TABLE `lock_table`  (
  `row_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `transaction_id` bigint NULL DEFAULT NULL,
  `branch_id` bigint NOT NULL,
  `resource_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `table_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `pk` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `status` tinyint NOT NULL DEFAULT 0 COMMENT '0:locked ,1:rollbacking',
  `gmt_create` datetime NULL DEFAULT NULL,
  `gmt_modified` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`row_key`) USING BTREE,
  INDEX `idx_status`(`status` ASC) USING BTREE,
  INDEX `idx_branch_id`(`branch_id` ASC) USING BTREE,
  INDEX `idx_xid`(`xid` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of lock_table
-- ----------------------------

-- ----------------------------
-- Table structure for undo_log
-- ----------------------------
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log`  (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `branch_id` bigint NOT NULL,
  `xid` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
  `context` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `ux_undo_log`(`xid` ASC, `branch_id` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of undo_log
-- ----------------------------

SET FOREIGN_KEY_CHECKS = 1;


3.在Nacos中创建,分布式事务命名空间,并在命名空间下创建ruoyiSeata.properties配置文件【并指定job模块和system模块需要进行分布式事务】

# 数据存储方式,db代表数据库
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
## mysql 5.xx
## driverClassName = "com.mysql.jdbc.Driver"
## mysql 8.0
driverClassName = "com.mysql.cj.jdbc.Driver"
# 对应导入的数据库
store.db.url=jdbc:mysql://xx.xx.xx.xx:3306/seate?useUnicode=true&rewriteBatchedStatements=true&useSSL=false
store.db.user=xxx
store.db.password=xxx
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.distributedLockTable=distributed_lock

# 对应 ${spring.application.name}-group,指定需要分布式事务的模块
service.vgroupMapping.ruoyi-job-group=default
service.vgroupMapping.ruoyi-system-group=default
      
store.db.maxWait=5000
# 事务、日志等配置
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000

# 客户端与服务端传输方式
transport.serialization=seata
transport.compressor=none
# 关闭metrics功能,提高性能
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

   配置结果如下:

在这里插入图片描述


4.配置seata

    打开解压的seata文件目录,找到conf/application.yml文件,并打开编辑

server:
 port: 7091

spring:
 application:
   name: ruoyiSeata-server  # 这是一个Spring Boot应用程序,当前应用的名称为 ruoyiSeata-server

logging:
 config: classpath:logback-spring.xml
 file:
   path: ${log.home:${user.home}/logs/seata}
 extend:
   logstash-appender:
     destination: 127.0.0.1:4560
   kafka-appender:
     bootstrap-servers: 127.0.0.1:9092
     topic: logback_to_logstash

console:
 user:
   username: seata
   password: seata
seata:
 # 指定 Seata 事务服务的组名为 my-tx-group。
 # 这在分布式事务中用来标识一组全局事务,各个微服务在参与分布式事务时,会使用这个组名来注册并加入到同一个事务协调中
 # 自定义:可以是任何你希望的字符串,包括随机生成的字符串
 tx-service-group: my-tx-group  
 
 config:
   type: nacos
   nacos:
     server-addr: xx.xx.xx.xx:8848  # 对应nacos地址
     context-path: /nacos  # 如果不使用代理(如nginx)可不写,后续解释
     data-id: ruoyiSeata.properties  # 对应【分布式事务命名空间 ruoyi_seata】下创建ruoyiSeata.properties配置文件
     namespace: d10a9eb9-82b9-4c06-b8f4-9aa46a5aff4a  # 对应分布式事务命名空间
     
 registry:
   type: nacos
   nacos:
     application: ruoyiSeata-server 
     server-addr: xx.xx.xx.xx:8848  # 对应nacos地址
     cluster: default
     context-path: /nacos  # 如果不使用代理(如nginx)可不写,后续解释
     namespace: d10a9eb9-82b9-4c06-b8f4-9aa46a5aff4a   # 对应分布式事务命名空间
     
 store:
   mode: file
   
#server:
#service-port: 8091 #If not configured, the default is '${server.port} + 1000'
 security:
   secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
   tokenValidityInMilliseconds: 1800000
   ignore:
     urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login

    context-path: /nacos说明


Nginx 配置:

upstream nacos_servers {
    server nacos-server-1:8848;
    server nacos-server-2:8848;
}

server {
    listen 80;

    location /nacos/ {
        proxy_pass http://nacos_servers/nacos/;
    }
}
请求路径:

客户端发出的请求路径为 http://nginx-server/nacos/v1/cs/configs。
Nginx 将此请求转发为 http://nacos-server-1:8848/nacos/v1/cs/configs,Nacos 接收到的是正确的路径,因为它配置了上下文路径 /nacos。

如果没有设置上下文路径,而 Nginx 将请求的路径多加了一层 /nacos,会因为找不到对应的 API 而报错。

    打开解压的seata文件目录,进入bin文件夹,双击seata-server.bat启动seata服务


5.需要使用分布式事务的模块引入依赖

<dependency>
 	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

5.配置需要分布式事务的模块[job、system],对应内容可以放在nacos配置文件中,也可以写在bootstrap.yml

    job模块添加seata配置

seata:
  enabled: true
  application-id: ruoyi-job
  # Seata 事务组编号,用于 TC 集群名
  tx-service-group: ruoyi-job-group
  service:
    vgroup-mapping:
      ruoyi-job-group: default
  config:
    type: nacos
    nacos:
      server-addr: xx.xx.xx.xx:8848  # 对应nacos地址
      group: DEFAULT_GROUP
      data-id: ruoyiSeata.properties # 对应【分布式事务命名空间 ruoyi_seata】下创建ruoyiSeata.properties配置文件
      namespace: d10a9eb9-82b9-4c06-b8f4-9aa46a5aff4a # 对应分布式事务命名空间
  registry:
    type: nacos
    nacos:
      application: ruoyiSeata-server # 对应`conf/application.yml`中registry.nacos.application
      server-addr: xx.xx.xx.xx:8848  # 对应nacos地址
      cluster: default
      group: DEFAULT_GROUP
      namespace: d10a9eb9-82b9-4c06-b8f4-9aa46a5aff4a # 对应分布式事务命名空间

    system模块添加seata配置

seata:
  enabled: true
  application-id: ruoyi-system
  # Seata 事务组编号,用于 TC 集群名
  tx-service-group: ruoyi-system-group
  service:
    vgroup-mapping:
      ruoyi-system-group: default
  config:
    type: nacos
    nacos:
      server-addr: xx.xx.xx.xx:8848  # 对应nacos地址
      group: DEFAULT_GROUP
      data-id: ruoyiSeata.properties # 对应【分布式事务命名空间 ruoyi_seata】下创建ruoyiSeata.properties配置文件
      namespace: d10a9eb9-82b9-4c06-b8f4-9aa46a5aff4a # 对应分布式事务命名空间
  registry:
    type: nacos
    nacos:
      application: ruoyiSeata-server # 对应`conf/application.yml`中registry.nacos.application
      server-addr: xx.xx.xx.xx:8848  # 对应nacos地址
      cluster: default
      group: DEFAULT_GROUP
      namespace: d10a9eb9-82b9-4c06-b8f4-9aa46a5aff4a # 对应分布式事务命名空间

6.使用时,在对应的方法名上追加注解@GlobalTransactional(rollbackFor = Exception.class),即可实现分布式事务
例如:

@GlobalTransactional(rollbackFor = Exception.class)
    public void aa() {
        SysUser sysUser = new SysUser();
        sysUser.setDeptId(105L);
        sysUser.setUserName("aa");
        sysUser.setPassword("aa");
        sysUser.setNickName("aa");
        // 远程调用,修改数据库
        AjaxResult ajaxResult = remoteUserService.insertUser(sysUser);
        throw new RuntimeException("报错了");
    }

在抛出异常后,远程调用的操作同样会进行回滚

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值