微服务+Seata解决分布式事务

好久没记录了,记录一下在若依微服务框架用Seata1.4.0解决,因远程调用导致事务不一致问题。

版本说明

本例于windows基于Nacos配置注册,数据库为Mysql,示例代码为Seata的AT模式

安装之前请先了解官方文档https://seata.apache.org/zh-cn/docs/v1.4/user/quickstart/

安装Seata服务器

1.下载资源

seata-server官网,二进制下载 文件名为1.4.0.zip

下载后目录如下图所示,解压

2.修改配置文件

我们进入conf目录,修改配置文件file.conf、registry.conf否则启动不起来

A、修改file.conf
B、新建数据库hny-seata

并且初始化,脚本如下

复制代码
/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 80026
 Source Host           : localhost:3306
 Source Schema         : hny-seata

 Target Server Type    : MySQL
 Target Server Version : 80026
 File Encoding         : 65001

 Date: 27/05/2026 11:39:13
*/

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(0) NOT NULL,
  `xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `transaction_id` bigint(0) 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(0) 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`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- 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(0) NULL DEFAULT NULL,
  `status` tinyint(0) 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(0) NULL DEFAULT NULL,
  `begin_time` bigint(0) NULL DEFAULT NULL,
  `application_data` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `gmt_create` datetime(0) NULL DEFAULT NULL,
  `gmt_modified` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`xid`) USING BTREE,
  INDEX `idx_gmt_modified_status`(`gmt_modified`, `status`) USING BTREE,
  INDEX `idx_transaction_id`(`transaction_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- 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(96) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `transaction_id` bigint(0) NULL DEFAULT NULL,
  `branch_id` bigint(0) 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,
  `gmt_create` datetime(0) NULL DEFAULT NULL,
  `gmt_modified` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`row_key`) USING BTREE,
  INDEX `idx_branch_id`(`branch_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for undo_log
-- ----------------------------
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log`  (
  `branch_id` bigint(0) NOT NULL COMMENT 'branch transaction id',
  `xid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'global transaction id',
  `context` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'undo_log context,such as serialization',
  `rollback_info` longblob NOT NULL COMMENT 'rollback info',
  `log_status` int(0) 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 INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'AT transaction mode undo table' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
C.修改registry.conf

在 Seata 服务器的配置文件 registry.conf 中配置 Nacos 注册中心

复制代码
registry {
  type = "nacos"
  nacos {
    application = "seata-server"
    serverAddr = "localhost:8848"
    group = "SEATA_GROUP"
    namespace = ""  nacos命令空间默认,可以直接去掉
    cluster = "default"
    username = "nacos" nacos账号密码默认是无,可以直接去掉
    password = "nacos"
  }
}

config {
  type = "nacos"
  nacos {
    serverAddr = "localhost:8848"
    group = "SEATA_GROUP"
    namespace = ""
    username = "nacos"
    password = "nacos"
  }
}
​

调整后结果如下图:

3.启动服务器

运行seata之前需要先保证nacos是启动的。可以正常访问nacos

直接在D:\software\seata-server-1.4.0\seata\bin 双击seata-server.bat

类似下图

没报错就是启动成功了,在nacos服务列表中可以看到注册的seata服务,由于服务我并没有配置命名空间,只指定了分组,因此在public命名空间里能看到此服务,各位按需要在registry.conf修改即可。

到此为止服务端完成。

配置客户端

1.引入坐标
复制代码
    <dependencies>
        <!-- SpringBoot Seata -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        </dependency>
    </dependencies>
2.项目模块yml配置
复制代码
spring:
  datasource:
    dynamic:
      datasource:
          # 主库数据源
          master:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://localhost:3306/hny-cloud2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
            username: root
            password: w123456
      seata: true    #开启seata代理,开启后默认每个数据源都代理,如果某个不需要代理可单独关闭

seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: hny-group 
  enable-auto-data-source-proxy: true   #是否开启数据源自动代理
  service:
    vgroup-mapping:
      hny-group: default
       # 直接指定Seata服务端地址,兜底保证能连上
    grouplist:
      default: 127.0.0.1:8091
3.微服务对应数据库中添加undo_log

seata需要在每个业务库添加一张undo_log表

复制代码
CREATE TABLE `undo_log` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint NOT NULL COMMENT 'branch transaction id',
  `xid` varchar(100) 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 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',
	PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='AT transaction mode undo table';
4.使用全局注解

5.回滚结果

相关推荐
笨鸟先飞的橘猫7 小时前
skynet——分布式支持
分布式·skynet
ACP广源盛1392462567311 小时前
GSV6155 @ACP#工业车规 DP1.4 重定时器 Retimer
大数据·人工智能·分布式·嵌入式硬件
ACP广源盛1392462567311 小时前
GSV2221@ACP# DP1.4 MST 多流显示转换芯片国产工业多屏
大数据·人工智能·分布式·嵌入式硬件·spark
ACP广源盛1392462567312 小时前
GSV2231@ACP# 增强型 8K MST 多屏扩展芯片
大数据·人工智能·分布式·嵌入式硬件
虚心的百褶裙12 小时前
远程调用服务架构设计及zookeeper技术详解(下篇)
分布式·zookeeper·云原生
清晨曦月13 小时前
【从零构建分布式在线评测系统】二、Judge0服务器上的心跳程序
运维·服务器·分布式
万联WANFLOW1 天前
SD-WAN 控制平面高可用怎么做?SDWAN 控制器挂了,全网会发生什么
运维·网络·分布式·架构
月落归舟1 天前
从单机到分布式:互联网系统架构演进全流程
分布式·系统架构
搬砖柯2 天前
系列12-接口压测怎么做成平台能力?自研 httpx 引擎、分布式 Worker 与 Locust 选型对照
分布式·测试工具·性能优化·开源·自动化·httpx
折哥的程序人生 · 物流技术专研2 天前
Java面试通关⑭:分布式理论与架构全集
分布式·微服务·校招·分布式事务·cap·java面试·最终一致性