当前位置: 首页 > news >正文

[特殊字符] 分布式事务中,@GlobalTransactional 与 @Transactional 到底怎么配合用?

在微服务架构中,随着系统模块的拆分,单体应用中的本地事务已经无法满足跨服务的数据一致性需求。此时,我们就需要引入分布式事务解决方案,比如 Seata。在使用 Seata 的过程中,很多人会遇到一个常见的疑问:

💬“我在调用方加了 @GlobalTransactional,服务提供方还需要加 @Transactional 吗?”

答案是:必须要加!

这篇文章我们就深入讲清楚:为什么服务提供方还需要加 @Transactional,以及两者如何协作实现真正可靠的分布式事务。


🧩 一、事务的两种类型

在讨论这个问题之前,我们先要明确两个事务注解的含义。

✅ 1. @GlobalTransactional(Seata 分布式事务)
  • 加在调用方法上,表示开启一个全局事务

  • 属于 Seata 的 AT 模式 事务注解,由 Seata 的 Transaction Coordinator (TC) 负责协调。

  • 它会自动传播全局事务上下文给远程调用的服务。

✅ 2. @Transactional(Spring 本地事务)
  • 加在某个服务的方法上,表示方法内部的数据库操作需要 在同一个本地事务中进行

  • 只有方法内部的操作在同一个本地事务中,Seata 才能在全局事务失败时,正确地让这些操作回滚。


📌 二、真实业务场景还原

我们以一个真实的订单系统为例:

👇 业务流程:
  1. 用户在订单服务(A)中下单。

  2. 系统同时调用库存服务(B)扣减库存。

  3. 库存服务还会记录一条扣减日志到另一个表。

❗ 错误示范(服务B没加 @Transactional):
// A服务
@GlobalTransactional
public void createOrder() {orderMapper.insert(order);inventoryFeign.decreaseStock(); // 远程调用 B 服务
}
// B服务
public void decreaseStock() {stockMapper.decrease();   // 成功logMapper.insertLog();    // 失败,抛异常
}

这时候会发生什么?

  • A服务使用 @GlobalTransactional,Seata 启动了全局事务。

  • B服务没有使用 @Transactional,所以两个表的操作并不在同一个本地事务中

  • 如果 logMapper.insertLog() 抛出异常,虽然 Seata 会通知回滚,但由于 stockMapper.decrease() 已经提交,数据就不一致了!

✅ 正确示范(服务B加上 @Transactional):
// B服务
@Transactional
public void decreaseStock() {stockMapper.decrease();   // 与下方操作属于同一个本地事务logMapper.insertLog();
}

现在当 logMapper.insertLog() 抛出异常时:

  • Spring 会将整个 decreaseStock 方法回滚。

  • Seata 能检测到异常,通知所有参与者事务回滚。

  • 整个流程变成原子性的。


🔍 三、Seata 的本质:全局事务 + 本地事务协同

Seata 做的不是“接管”你的数据库事务,而是:

在每个服务节点中使用代理数据源(DataSourceProxy),通过拦截本地事务的提交/回滚操作,来实现 全局的一致性控制

因此:

  • @GlobalTransactional 控制“何时开始、是否提交全局事务”

  • @Transactional 保证“本地数据库操作的一致性和可回滚性”

你不加 @Transactional,Seata 就没法让你的数据库事务回滚,因为根本没事务!


🛠 四、项目接入建议

如果你要使用 Seata 进行分布式事务控制,务必注意以下几点:

配置项说明
✅ @GlobalTransactional放在业务流程发起方(一般是 Controller 或 Service)
✅ @Transactional放在服务提供方处理数据库操作的 Service 方法上
✅ 使用 Seata 的 DataSourceProxy所有数据源都要通过 Seata 的代理包装
✅ 注册到 Seata Server服务注册中心需正确配置 Seata 服务

📚 五、总结

@GlobalTransactional 是分布式事务的起点,@Transactional 是本地事务的保障,二者缺一不可。

在微服务的世界里,要实现数据一致性,必须让每个参与者都对自己的事务负责。Seata 会协调所有本地事务的提交和回滚,但它不会、也无法替你加上事务控制。


如果你觉得这篇文章对你有帮助,欢迎点赞、评论、收藏 ✅
有任何问题也欢迎私信或留言交流!


📌 附推荐阅读:

  • Seata 官方文档

  • Spring Transactional 源码解析

  • [分布式事务解决方案对比(Seata、TCC、消息最终一致性)]

http://www.xdnf.cn/news/110197.html

相关文章:

  • Python爬虫实战:获取xie程网敦煌景点数据,为51旅游路线做参考
  • Python实现图片浏览器
  • 连锁美业管理系统「数据分析」的重要作用分析︳博弈美业系统疗愈系统分享
  • 使用 Python 打造强大的文件分析工具
  • 海量粒子特效解决方案:VEG
  • java六人打分
  • 高效并发编程:无锁编程
  • 字节系a_bogus补环境
  • 浏览器相关知识点
  • 路由交换实验-手动聚合与LACP
  • 自动创建 中国古代故事人物一致性图画,看看扣子的空间是否能达到你的满意,自媒体的福音?
  • 【KWDB 创作者计划】_上位机知识篇---MicroPython
  • 一,开发环境安装
  • w~大模型~合集13
  • AUTODL关闭了程序内存依然占满怎么办
  • 〖 Linux 〗掌握 Linux 共享目录:权限、管理与最佳实践
  • 防火墙事件日志及日志分析
  • Python数据清洗笔记(上)
  • 文件内容隐写
  • 面向电力变压器的声纹智能诊断系统简析
  • Springfox + Swagger 的完整配置及同类框架对比的详细说明
  • (即插即用模块-特征处理部分) 四十一、(2024) MSAA 多尺度注意力聚合模块
  • 我的独立开发技术栈
  • 未曾设想的道路1
  • Ubuntu22.04新版本谷歌无法使用搜狗输入法/中文不显示
  • 三、Python编程基础03
  • 使用Python模拟子弹与子弹的碰撞
  • 四神-华夏大地的守护神
  • 【AI】MCP,弥补Agent的缺陷
  • 一个关于相对速度的假想的故事-7