springboot 项目集成 seate 分布式事务AT模式使用nacos完整配置步骤及说明

在 Spring Boot 项目中集成 Seata AT 模式 并使用 Nacos 作为注册中心和配置中心,是实现分布式事务的主流方案。以下是 完整、清晰、可操作性强 的配置步骤及说明(适用于 Spring Boot 3.x + Spring Cloud Alibaba 2023.x + Seata 2.0.0+ + Nacos 2.x)。


✅ 一、整体架构说明

  • TC(Transaction Coordinator):Seata Server,负责协调全局事务。
  • TM(Transaction Manager) :发起全局事务的服务(如订单服务),用 @GlobalTransactional 注解。
  • RM(Resource Manager):参与分支事务的服务(如库存、支付服务),自动注册到 TC。
  • Nacos :同时作为 服务注册中心 和 配置中心。
  • AT 模式:基于数据库代理(DataSourceProxy)自动生成 undo_log 实现回滚。

✅ 二、前置准备

组件 版本建议
JDK 17
Maven 3.8+
MySQL 8.0
Nacos 2.2.x ~ 2.3.x
Seata Server 2.0.0
Spring Boot 3.2.x
Spring Cloud Alibaba 2023.0.1.0

⚠️ 注意:Seata 2.0.0 起推荐使用 application.yml 配置,不再依赖 registry.conf 和 file.conf。


✅ 三、部署 Seata Server(TC)

1. 下载并解压 Seata Server

复制代码
wget https://github.com/seata/seata/releases/download/v2.0.0/seata-server-2.0.0.tar.gz
tar -zxvf seata-server-2.0.0.tar.gz

2. 初始化 Seata 数据库

在 MySQL 中创建 seata 库,并执行脚本:

复制代码
-- 脚本位置:seata/script/server/db/mysql.sql
CREATE DATABASE seata;
USE seata;
-- 执行 mysql.sql 创建 global_table, branch_table, lock_table

3. 配置 seata/conf/application.yml

复制代码
seata:
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace: ""  # 或指定命名空间ID
      username: nacos
      password: nacos
      data-id: seataServer.properties  # 自定义配置文件名
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace: ""
      cluster: default
      username: nacos
      password: nacos
  store:
    mode: db
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
      user: root
      password: your_password

4. 在 Nacos 中添加 seataServer.properties

Data ID: seataServer.properties

Group: SEATA_GROUP

内容示例:

复制代码
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
store.db.user=root
store.db.password=your_password

5. 启动 Seata Server

复制代码
cd seata/bin
./seata-server.sh -h 127.0.0.1 -p 8091 -m db

✅ 启动后,在 Nacos 控制台应能看到 seata-server 服务注册成功。


✅ 四、Spring Boot 微服务配置(TM / RM)

以 order-service 为例,其他服务(stock、payment)类似。

1. 添加 Maven 依赖(pom.xml)

复制代码
<dependencies>
    <!-- Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Nacos Discovery -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2023.0.1.0</version>
    </dependency>

    <!-- Seata -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        <version>2023.0.1.0</version>
    </dependency>

    <!-- MySQL & MyBatis -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
</dependencies>

2. 配置 application.yml

复制代码
spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos

seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: my_tx_group  # ⚠️ 关键:必须与 vgroup-mapping 对应
  data-source-proxy-mode: AT
  enable-auto-data-source-proxy: false  # 手动代理更可控(推荐)
  registry:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace: ""
      username: nacos
      password: nacos
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace: ""
      username: nacos
      password: nacos
      data-id: seataServer.properties
  service:
    vgroup-mapping:
      my_tx_group: default  # ⚠️ 必须与 tx-service-group 一致
    grouplist:
      default: 127.0.0.1:8091  # 兼容旧版,Seata 2.0+ 可省略(通过 Nacos 发现)

💡 enable-auto-data-source-proxy: false 表示手动创建 DataSourceProxy,避免与多数据源冲突。

3. 手动创建 DataSource 代理(关键!)

复制代码
@Configuration
public class SeataDataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource")
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }

    @Primary
    @Bean("dataSource")
    public DataSource dataSource(DruidDataSource druidDataSource) {
        return new DataSourceProxy(druidDataSource);
    }
}

✅ 必须使用 DataSourceProxy 包装原始数据源,Seata 才能拦截 SQL 并生成 undo_log。

4. 每个微服务数据库中创建 undo_log 表

复制代码
-- 每个业务库(order_db, stock_db, payment_db)都要执行
CREATE TABLE `undo_log` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `branch_id` BIGINT(20) NOT NULL,
  `xid` VARCHAR(100) NOT NULL,
  `context` VARCHAR(128) NOT NULL,
  `rollback_info` LONGBLOB NOT 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=utf8mb4;

✅ 五、编写分布式事务代码

TM 端(订单服务)------ 发起全局事务

复制代码
@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping("/createOrder")
    @GlobalTransactional(name = "create-order-tx", rollbackFor = Exception.class)
    public String createOrder(@RequestBody OrderDTO dto) {
        orderService.createOrder(dto); // 内部调用 stock-service 和 payment-service
        return "success";
    }
}

RM 端(库存/支付服务)------ 只需普通本地事务

复制代码
@Service
public class StockService {

    @Transactional
    public void deductStock(Long productId, Integer count) {
        // 扣减库存
        stockMapper.updateStock(productId, count);
        // 模拟异常:throw new RuntimeException("库存不足");
    }
}

✅ RM 不需要任何 Seata 注解,只需保证方法上有 @Transactional。


✅ 六、验证与调试

  1. 启动顺序 :
    • 启动 Nacos
    • 启动 Seata Server
    • 启动所有微服务
  2. 检查项 :
    • Nacos 控制台:seata-server 和各微服务是否注册?
    • 数据库:各业务库是否有 undo_log 表?
    • 日志:Seata Client 是否连接到 TC?
  3. 测试场景 :
    • 正常流程:全部提交
    • 异常流程(如库存不足):全部回滚,undo_log 被清理

✅ 七、常见问题排查

问题 解决方案
no available service 'default' 检查 tx-service-group 与 vgroup-mapping 是否一致
无法连接 Seata Server 检查 Nacos 中 seata-server 是否在线,端口 8091 是否开放
undo_log 未生成 确认使用了 DataSourceProxy,且方法上有 @Transactional
Seata 2.0 配置不生效 放弃 registry.conf,统一使用 application.yml

✅ 总结

通过以上步骤,你已成功在 Spring Boot 项目中集成 Seata AT 模式 + Nacos,实现强一致的分布式事务。核心要点:

  • Seata Server 用 Nacos 注册 & 配置
  • 客户端手动代理 DataSource
  • 每个业务库建 undo_log 表
  • **TM 用 @GlobalTransactional ,RM 用普通 **@Transactional

📌 完整项目结构建议参考官方示例或 GitHub 开源项目(如 seata/samples)。

如需进一步优化(如高可用 TC 集群、多命名空间隔离等),可在此基础上扩展。

相关推荐
带金箍的至尊宝2 小时前
系统架构设计师笔记 05:第2章硬件与软件基础,冯诺依曼结构怎么考
数据库·笔记·系统架构
Jmyd01233 小时前
智慧文博三维重建系统架构设计:从结构光采集到平台交付全链路
系统架构
各类产品分享14 小时前
钢铁厂 AR 设备点检系统架构设计与落地实践
系统架构·ar·ar巡检
HRTOS7 小时前
HRTOS 4.0 内核资源配置优化:减少资源对象与消息队列数量
经验分享·单片机·系统架构·51单片机
省钱兄--zs7 小时前
24小时自助健身房系统软件开发实战:从架构设计到部署全指南
java·数据仓库·spring boot·系统架构·需求分析
tianyuanwo8 小时前
【软考高级系统架构设计师】05 - DevOps & CI/CD专题备考
ci/cd·系统架构·devops
tianyuanwo9 小时前
【软考高级系统架构设计师】02 - 架构评估专题备考
系统架构
数智工坊9 小时前
视觉SLAM第13讲|工程落地:双目视觉里程计系统架构设计与性能优化
人工智能·深度学习·线性代数·性能优化·矩阵·系统架构·机器人
省钱兄--zs21 小时前
西安24小时自助健身房解决方案实战:系统开发与部署全流程指南
java·spring boot·系统架构·intellij-idea·需求分析
weixin_1772972206921 小时前
从零搭建企业AI知识库:系统架构与核心模块拆解
人工智能·系统架构