分布式事务 Seata 与链路追踪 SkyWalking 全解析

一、事务基础认知

1.1 本地事务

事务是数据库操作的基本单元,用于保证一组 SQL 语句的原子性执行 ------ 要么全部成功执行并提交,要么全部失败回滚。

数据库事务核心遵循 ACID 原则:

  • 原子性(Atomicity):事务是最小执行单位,不可拆分
  • 一致性(Consistency):事务执行前后数据状态始终合法
  • 隔离性(Isolation):并发事务间相互隔离,互不干扰
  • 持久性(Durability):事务提交后,数据修改永久生效
本地事务的实现方式
  1. 数据库原生控制
sql 复制代码
START TRANSACTION
  -- 保存订单
  INSERT INTO tb_order (item_id, num) VALUES (1, 2);
  -- 扣减库存
  UPDATE tb_item SET num = num - 2 WHERE id = 1;
-- 失败回滚/成功提交
ROLLBACK; -- COMMIT;
  1. JDBC 编程式事务
java 复制代码
Connection conn = getConnection();
try {
    conn.setAutoCommit(false); // 关闭自动提交
    Statement stmt = conn.createStatement();
    stmt.executeUpdate("INSERT INTO tb_order ...");
    stmt.executeUpdate("UPDATE tb_item ...");
    conn.commit(); // 手动提交
} catch (Exception e) {
    conn.rollback(); // 异常回滚
} finally {
    conn.close();
}
  1. Spring 声明式事务(AOP)
java 复制代码
@Transactional // 事务注解
public void insertOrder(TbOrder tbOrder) {
    // 保存订单
    tbOrderMapper.insertSelective(tbOrder);
    // 扣减库存
    itemService.updateItem(tbOrder.getItemId(), tbOrder.getNum());
}

1.2 分布式事务

随着微服务架构普及,业务操作往往跨多个服务 / 数据库,此时本地事务无法保证全局一致性,分布式事务应运而生。

分布式事务产生场景
  1. 跨微服务调用:订单服务调用库存服务扣减库存,跨 JVM 进程
  2. 跨数据库实例:单体应用操作多个 MySQL 实例(用户库 + 订单库)
  3. 多服务操作同一数据库:不同服务持有独立数据库连接,仍会产生分布式事务
分布式事务的核心问题

传统本地事务在分布式场景下失效:

java 复制代码
@Transactional
public void insertOrder(TbOrder tbOrder) {
    // 本地保存订单(成功)
    tbOrderMapper.insertSelective(tbOrder);
    // 远程调用扣减库存(成功)
    itemServiceFeign.updateItem(tbOrder.getItemId(), tbOrder.getNum());
    // 模拟异常,本地事务回滚,但库存已扣减
    int a = 6 / 0;
}

二、分布式事务解决方案 - Seata

2.1 Seata 核心概念

Seata(Simple Extensible Autonomous Transaction Architecture)是阿里开源的分布式事务框架,目标是让分布式事务使用像本地事务一样简单。

核心组件
  • TC(Transaction Coordinator):事务协调器,维护全局事务状态,协调提交 / 回滚
  • TM(Transaction Manager):事务管理器,定义全局事务范围,发起全局提交 / 回滚
  • RM(Resource Manager):资源管理器,管理本地事务,向 TC 注册分支事务
Seata 事务模式
模式 一致性 可用性 业务侵入 适用场景
XA 强一致 金融核心场景
TCC 最终一致 定制化业务
AT 最终一致 通用业务(默认)
SAGA 最终一致 最高 长事务场景

2.2 AT 模式工作流程(重点)

AT 模式是 Seata 默认推荐的无侵入方案,分为两个阶段:

一阶段(本地事务提交)
  1. 解析 SQL,提取表名、条件、修改内容
  2. 查询前镜像:执行 SQL 前的数据状态
sql 复制代码
SELECT id, name, num FROM tb_item WHERE id = 1;
  1. 执行业务 SQL:UPDATE tb_item SET num = 98 WHERE id = 1;
  2. 查询后镜像:执行 SQL 后的数据状态
  3. 插入回滚日志到undo_log表,记录前后镜像与 SQL 信息
  4. 向 TC 注册分支事务,申请全局锁
  5. 提交本地事务,上报事务状态给 TC
二阶段
  • 回滚 :TC 下发回滚指令,RM 根据undo_log中的前镜像生成回滚 SQL,恢复数据
  • 提交 :TC 下发提交指令,RM 删除undo_log日志(异步执行,性能高)

2.3 Seata 环境搭建

1. 下载与解压

bash:

复制代码
# 下载地址:https://github.com/seata/seata/releases
tar -zxvf seata-server-1.4.2.tar.gz -C /usr/local/
2. 配置注册中心(Nacos)

修改conf/registry.conf

properties:

复制代码
registry {
  type = "nacos"
  nacos {
    application = "seata-server"
    serverAddr = "192.168.204.129:8848"
    group = "SEATA_GROUP"
    cluster = "default"
  }
}
config {
  type = "nacos"
  nacos {
    serverAddr = "192.168.204.129:8848"
    group = "SEATA_GROUP"
    dataId = "seataServer.properties"
  }
}
3. 配置数据源(Nacos 配置中心)

添加配置项seataServer.properties

properties:

复制代码
store.mode=db
store.db.dbType=mysql
store.db.url=jdbc:mysql://192.168.61.130:3306/seata?useSSL=false
store.db.user=root
store.db.password=1111
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.lockTable=lock_table
4. 创建 TC 数据库表
sql 复制代码
CREATE DATABASE seata;
USE seata;

-- 全局事务表
CREATE TABLE `global_table` (
  `xid` VARCHAR(128) NOT NULL,
  `status` TINYINT NOT NULL,
  PRIMARY KEY (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 分支事务表
CREATE TABLE `branch_table` (
  `branch_id` BIGINT NOT NULL,
  `xid` VARCHAR(128) NOT NULL,
  PRIMARY KEY (`branch_id`),
  KEY `idx_xid` (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 锁表
CREATE TABLE `lock_table` (
  `row_key` VARCHAR(128) NOT NULL,
  `branch_id` BIGINT NOT NULL,
  PRIMARY KEY (`row_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
5. 启动 Seata Server

bash:

复制代码
cd /usr/local/seata/bin
./seata-server.sh -h 192.168.61.133 -p 8091

2.4 微服务整合 Seata

1. 依赖引入(所有参与事务的服务)
XML 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
2. 配置文件(application.yml)

yaml:

复制代码
seata:
  registry:
    type: nacos
    nacos:
      server-addr: 192.168.204.129:8848
      group: SEATA_GROUP
      application: seata-server
  tx-service-group: seata-demo
  service:
    vgroup-mapping:
      seata-demo: default
3. 业务改造(事务发起方)
java 复制代码
@GlobalTransactional // 替换@Transactional,开启全局事务
public void insertOrder(TbOrder tbOrder) {
    // 保存订单(本地事务)
    tbOrderMapper.insertSelective(tbOrder);
    // 远程调用扣减库存(分支事务)
    itemServiceFeign.updateItem(tbOrder.getItemId(), tbOrder.getNum());
    // 异常时全局回滚
    int a = 6 / 0;
}
4. 效果验证
  • 异常发生时,订单插入和库存扣减会全局回滚
  • 无异常时,所有分支事务正常提交

三、链路追踪 SkyWalking

3.1 为什么需要 SkyWalking

微服务架构下,一个请求可能经过多个服务调用(如:用户下单→订单服务→库存服务→支付服务),传统日志监控无法清晰追踪请求全链路:

  • 定位慢查询 / 异常节点困难
  • 无法直观看到服务间依赖关系
  • 缺乏全链路性能指标分析

3.2 SkyWalking 核心定位

SkyWalking 是国产开源 APM(应用性能管理)工具,由吴晟开源并纳入 Apache 基金会,核心能力:

  • 分布式追踪:追踪请求全链路,定位异常节点
  • 性能指标分析:监控服务 / 接口响应时间、QPS 等
  • 服务依赖分析:可视化展示服务间调用关系
  • 告警监控:自定义阈值告警,及时发现问题

3.3 SkyWalking 核心优势

  1. 低侵入:支持无代码侵入的探针式接入(Agent)
  2. 多语言支持:Java/Go/Python 等主流语言
  3. 多数据源适配:支持监控 Elasticsearch/MySQL 等中间件
  4. 云原生友好:适配 Docker/K8s 等容器化环境

四、实操总结

  1. 分布式事务:Seata 通过 TC/TM/RM 架构,以 AT 模式实现无侵入的分布式事务管控,解决微服务跨服务 / 跨库的数据一致性问题。
  2. 链路追踪:SkyWalking 弥补了微服务架构下全链路监控的空白,是定位性能瓶颈、排查分布式问题的核心工具。
  3. 技术选型建议
    • 金融级强一致性场景:Seata XA 模式
    • 通用业务场景:Seata AT 模式
    • 微服务全链路监控:SkyWalking + Prometheus + Grafana

通过 Seata 解决分布式事务一致性问题,结合 SkyWalking 实现全链路可观测,可有效保障微服务架构的稳定性与可维护性。

相关推荐
giaz14n9X21 小时前
Redis 分布式锁进阶第五十七篇
数据库·redis·分布式
WyCAGy8ij1 天前
Redis 分布式锁进阶第二篇讲解
数据库·redis·分布式
冰西瓜6001 天前
深度学习的数学原理(四十二)—— 分布式训练
人工智能·分布式·深度学习
接着奏乐接着舞1 天前
springcloud skywalking
spring·spring cloud·skywalking
WyCAGy8ij1 天前
Redis 分布式锁进阶第四篇讲解
数据库·redis·分布式
MrJson-架构师1 天前
AgentScope Java 2.0:打造分布式、企业级智能体底座
java·开发语言·分布式
先跑起来再说1 天前
Go 排行榜系统的工程化实现:分布式锁、快照表与定时刷新
分布式·go·gin
ACP广源盛139246256731 天前
GSV2231 三屏显示扩展芯片@ACP#RTX Spark AI 终端多屏协作专属解决方案
大数据·人工智能·分布式·信息可视化·spark·电脑·音视频
探客木木夕1 天前
分布式全球类脑智能网络架构设计
网络·人工智能·分布式·边缘计算
周末也要写八哥2 天前
分布式技术之单机锁
分布式