[特殊字符] 分布式事务中,@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.mzph.cn/bicheng/78242.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TDengine 集群高可用方案设计(二)

四、TDengine 集群高可用方案设计 4.1 硬件与网络架构设计 服务器选型:选择配置高、稳定性强的服务器,如戴尔 PowerEdge R740xd、华为 RH2288H V5 等。以戴尔 PowerEdge R740xd 为例,它配备英特尔至强可扩展处理器,具备高性能计…

从对数变换到深度框架:逻辑回归与交叉熵的数学原理及PyTorch实战

目录 前言 一、连乘变连加二、最小化损失函数2.1交叉熵2.2 二分类交叉熵2.3 多分类交叉熵三、逻辑回归与二分类3.1 逻辑回归与二分类算法理论讲解3.1.1 散点输入3.1.2 前向计算3.1.3 Sigmoid函数引入3.1.4 参数初始化3.1.5 损失函数3.1.6 开始迭代3.1.7 梯度下降显示四、基于框…

高企复审奖补!2025年合肥市高新技术企业重新认定奖励补贴政策及申报条件

一、合肥市高新技术企业重新认定奖励补贴政策 (一)高新区高新技术企业重新认定复审补贴奖励 重新认定为国家高新技术企业的给予5万元一次性奖励。 (二)经开区高新技术企业重新认定复审补贴奖励 对重新认定的企业,给…

Spring Boot 中配置线程池时优化 `ThreadPoolTaskExecutor` 的配置总结

在 Spring Boot 中配置线程池时,可以通过以下方式进一步优化 ThreadPoolTaskExecutor 的配置,提升性能、灵活性和可靠性: 优化点 1:合理设置线程池参数 关键参数调整 Bean(name "taskExecutor") public Executor tas…

opencv 图像的旋转

图像的旋转 1 单点旋转2. 图片旋转(cv2.getRotationMatrix2D)3. 插值方法3.1 最近邻插值(cv2.INTER_NEAREST)3.2 双线性插值(cv2.INTER_LINEAR)3.3 像素区域插值(cv2.INTER_AREA)3.4 双三次插值(cv2.INTER_CUBIC&#…

如何在 Odoo 18 中配置自动化动作

如何在 Odoo 18 中配置自动化动作 Odoo是一款多功能的业务管理平台,旨在帮助各种规模的企业更高效地处理日常运营。凭借其涵盖销售、库存、客户关系管理(CRM)、会计和人力资源等领域的多样化模块,Odoo 简化了业务流程&#xff0c…

每日两道leetcode

345. 反转字符串中的元音字母 - 力扣(LeetCode) 题目 给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。 元音字母包括 a、e、i、o、u,且可能以大小写两种形式出现不止一次。 示例 1:…

【SQL 基础入门 1. -- SQL 基本语法详解及举例】

文章目录 SQL 数据库创建及使用删除数据库SQL 查看数据空中有哪些表格SQL 创建表格SQL 修改表格列数据格式SQL 表格插入数据SQL 查看表格类型组成SQL 查看表格中的内容 SQL 查询语句SQL 查看指定列SQL 选择指定列SQL 按指定列进行升序排序SQL 平均值/求和/最大值/最小值 SQL 数…

PostgreSQL 分区表——范围分区SQL实践

PostgreSQL 分区表——范围分区SQL实践 1、环境准备1-1、新增原始表1-2、执行脚本新增2400w行1-3、创建pg分区表-分区键为创建时间1-4、创建24年所有分区1-5、设置默认分区(兜底用)1-6、迁移数据1-7、创建分区表索引 2、SQL增删改查测试2-1、查询速度对比…

Apache Flink 深度解析:流处理引擎的核心原理与生产实践指南

Apache Flink 深度解析:流处理引擎的核心原理与生产实践指南 引言:实时计算的范式革命 2023年双十一期间,某头部电商平台基于Flink构建的实时风控系统成功拦截了每秒超过120万次的异常交易请求。这背后是Apache Flink作为第四代计算引擎的强…

【Java学习笔记】选择结构

选择结构 内容结构 一、顺序结构 二、分支控制 (1)单分支 (2)双分支 (3)多分支 (4)嵌套分支 (5)switch 分支结构 三、switch和if的比较 一、顺序结构…

03_JavaScript

文章目录 一、概述1.1、JavaScript简介1.2、JavaScript组成部分1.3、为什么要学习JavaScript1.4、学习的目的1.5、JavaScript与Java的关系 二、使用位置及运行说明2.1、使用位置2.2、如何运行 三、JavaScript基础语法3.1、变量3.2、运算符3.3、控制流程3.3.1、分支结构3.3.2、循…

PySide6 GUI 学习笔记——常用类及控件使用方法(常用类矩阵QRect)

文章目录 一、构造与初始化方法二、坐标与尺寸获取三、坐标与尺寸设置四、几何运算方法五、移动与调整方法六、状态判断方法七、类型转换方法八、操作符重载九、静态方法十、特殊方法附录方法速查表注意的问题交集和并集图解 📘 PySide6.QtCore.QRect 使用整数精度定…

AI 开发入门之 RAG 技术

目录 一、从一个简单的问题开始二、语言模型“闭卷考试”的困境三、RAG 是什么—LLM 的现实世界“外挂”四、RAG 的七步流程第一步:加载数据(Load)第二步:切分文本(Chunking)第三步:向量化&…

解决yarn install 报错 error \node_modules\electron: Command failed.

在电脑重装系统后,重新安装项目依赖,遇到这一报错 完整报错信息如下: error D:\xxxxx\xxxxxx\node_modules\electron: Command failed. Exit code: 1 Command: node install.js Arguments: Directory: D:\xxxxx\xxxxx\node_modules\electron Output: HTTPError: Response cod…

2025年3月电子学会青少年机器人技术(五级)等级考试试卷-理论综合

青少年机器人技术等级考试理论综合试卷(五级) 分数:100 题数:30 一、单选题(共20题,共80分) 1. 2025年初,中国科技初创公司深度求索在大模型领域迅速崛起,其开源的大模型成为全球AI领域的焦…

23种设计模式-行为型模式之模版方法模式(Java版本)

Java 模板方法模式(Template Method Pattern)详解 🧠 什么是模板方法模式? 模板方法模式是一种行为型设计模式,在一个方法中定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在…

长城杯铁人三项初赛-REVERSE复现

前言 记录记录 1.LoginToMe int __fastcall main(int argc, const char **argv, const char **envp) {unsigned int v3; // eaxchar s[96]; // [rsp10h] [rbp-70h] BYREFint v6; // [rsp70h] [rbp-10h]int v7; // [rsp78h] [rbp-8h]int i; // [rsp7Ch] [rbp-4h]memset(s, 0, s…

DNS实验

DNS原理 客户端发起请求:客户端向本地 DNS 服务器发送域名解析请求,这是流程的起始点。本地 DNS 服务器查询根域名服务器:若本地 DNS 服务器缓存中无对应记录,它向根域名服务器发起查询,根域名服务器是 DNS 系统顶层&a…

SQLMesh 通知系统深度解析:构建自动化监控体系

SQLMesh 是一款强大的数据编排工具,其内置的灵活通知系统可显著提升团队协作效率。本文将系统解读 SQLMesh 的通知机制,涵盖配置方法、事件触发逻辑及高级定制技巧。 一、通知系统的核心架构 1. 通知目标(Notification Targets) …