【JAVA】Java微服务—分布式事务框架Seata

Seata分布式事务框架

Nacos 解决"服务之间怎么找到彼此";

Seata 解决"多个服务一起操作数据库时,怎么保证要么都成功,要么都失败"。


1. 为什么需要 Seata?

假设你现在有两个微服务:

复制代码
order 服务:负责创建订单
stock 服务:负责扣减库存

用户下单时,流程可能是:

复制代码
1. order 服务创建订单
2. stock 服务扣减库存

正常情况下:

复制代码
订单创建成功
库存扣减成功

这没问题。

但是如果出现这种情况:

复制代码
订单创建成功
库存扣减失败

那就麻烦了。

因为数据库里会变成:

复制代码
订单表里有订单
库存表没有扣减

这就叫 数据不一致


2. 单体项目里事务很好解决

如果是单体项目,订单表和库存表都在一个服务里,可以直接用:

复制代码
@Transactional
public void createOrder() {
    // 创建订单
    // 扣减库存
}

如果中间出错,Spring 可以自动回滚。

也就是:

复制代码
要么订单和库存都成功
要么订单和库存都失败

3. 微服务项目里事务变复杂了

但是微服务中是这样:

复制代码
order 服务有自己的数据库
stock 服务有自己的数据库

结构类似:

复制代码
order 服务  →  order_db
stock 服务  →  stock_db

这时候 @Transactional 只能管住当前服务自己的数据库。

也就是说:

复制代码
@Transactional
public void addOrder() {
    // 这里只能保证 order_db 的事务
}

它管不了 stock 服务 的数据库。

所以问题来了:

复制代码
order 服务成功了
stock 服务失败了
谁来统一回滚?

这就是 Seata 要解决的问题。


4. Seata 是干什么的?

Seata 的作用是:

管理多个微服务之间的分布式事务。

比如下单流程:

复制代码
order 服务创建订单
stock 服务扣减库存
account 服务扣减余额

Seata 可以让它们变成一个整体事务:

复制代码
全部成功 → 提交
有一个失败 → 全部回滚

5. 用你的项目理解 Seata

你截图里有:

复制代码
order
stock

如果没有 Seata:

复制代码
用户请求 /order/add
    ↓
order 创建订单成功
    ↓
order 调用 stock 扣库存
    ↓
stock 扣库存失败
    ↓
结果:订单已经创建,但库存没扣

这就是不一致。

如果有 Seata:

复制代码
用户请求 /order/add
    ↓
order 创建订单
    ↓
stock 扣库存
    ↓
如果 stock 失败
    ↓
Seata 通知 order 回滚
    ↓
订单也撤销

最终结果:

复制代码
订单没有创建
库存也没有变化

数据保持一致。


6. Seata 的核心角色

Seata 里面有三个重要角色。

TC:事务协调者

TC 全称是:

复制代码
Transaction Coordinator

它是 Seata 的服务端。

作用是:

复制代码
统一管理整个分布式事务
决定最后是提交还是回滚

你可以理解成:

TC 是总指挥。


TM:事务管理器

TM 全称是:

复制代码
Transaction Manager

一般在发起事务的服务里。

比如 order 服务是整个下单流程的入口,那么 order 服务通常就是 TM。

它负责:

复制代码
开启全局事务
提交全局事务
回滚全局事务

你可以理解成:

TM 是这次事务的发起人。


RM:资源管理器

RM 全称是:

复制代码
Resource Manager

每个操作数据库的服务都可以看作 RM。

比如:

复制代码
order 服务操作 order_db
stock 服务操作 stock_db
account 服务操作 account_db

它们都是 RM。

RM 负责:

复制代码
执行本地数据库操作
向 TC 汇报状态
根据 TC 指令提交或回滚

你可以理解成:

RM 是具体干活的人。


7. Seata 的执行流程

以下单为例:

复制代码
1. order 服务开启全局事务
2. order 服务创建订单
3. order 服务调用 stock 服务
4. stock 服务扣减库存
5. 如果都成功,Seata 统一提交
6. 如果有失败,Seata 统一回滚

结构可以这样看:

复制代码
用户
 ↓
order 服务:TM + RM
 ↓
stock 服务:RM
 ↓
Seata Server:TC

8. 代码里一般怎么用?

在入口方法上加:

复制代码
@GlobalTransactional

例如:

复制代码
@GlobalTransactional
public String createOrder() {
    // 1. 创建订单

    // 2. 调用库存服务扣库存

    // 3. 如果中间出错,Seata 负责全局回滚

    return "下单成功";
}

注意区别:

复制代码
@Transactional:本地事务,只管当前服务自己的数据库
@GlobalTransactional:全局事务,可以管多个微服务

9. Seata 和 Nacos 是什么关系?

它们不是一个东西。

组件 作用
Nacos 服务注册、服务发现、配置中心
Seata 分布式事务
Sentinel 限流、熔断、降级
Gateway 网关
OpenFeign / RestTemplate 服务调用

在 Spring Cloud Alibaba 体系里,它们经常一起出现。

你可以这样理解:

复制代码
Nacos:帮服务互相找到
Seata:帮多个服务保持数据一致

10. 一句话总结

Seata 是用来解决微服务分布式事务问题的。

在你的 order + stock 项目里,它主要解决这个问题:

下单时,订单创建成功但扣库存失败怎么办?

有了 Seata,可以做到:

复制代码
订单创建和库存扣减,要么都成功,要么都失败。
相关推荐
Jul1en_2 小时前
【Redis】事务详解、WATCH 实现思想
java·spring boot·redis·mysql·java-ee
Wonderful U2 小时前
基于Python+Django的智能在线考试系统:从题库管理到自动阅卷的全流程实战
开发语言·python·django
SimonKing2 小时前
你还在靠重启来调线程池?别人已经做到了实时调控,3分钟接入
java·后端·程序员
无忧.芙桃2 小时前
数据结构之单链表
c语言·开发语言·数据结构
SilentSamsara2 小时前
Python 服务的 K8s 部署:HPA/ConfigMap/Secret 完整配置
开发语言·python·青少年编程·容器·kubernetes
小张小张爱学习2 小时前
Java并发编程面试题
java·开发语言
码不停蹄的玄黓2 小时前
JDK 自带四大命令行工具:jstat、jstack、jmap、jhat 详解
java·开发语言
ch.ju2 小时前
Java程序设计(第3版)第四章——set方法为属性赋值
java·开发语言
创业之路&下一个五年2 小时前
JS编程范式 \& 面向对象范式
开发语言·前端·javascript