本地事务在微服务中失效,因@transactional仅作用于单jvm内数据库连接,而微服务跨进程部署导致多数据源无法被统一管理,必须改用分布式事务或最终一致性方案。

为什么本地事务在微服务里直接失效
因为 @Transactional 只能控制单个 JVM 内的数据库连接,而微服务拆分后,订单服务、库存服务、支付服务通常部署在不同进程甚至不同机器上。一个跨服务的操作(比如“下单扣库存+创建支付单”)天然涉及多个数据源,@Transactional 根本管不到别的服务里的数据库事务。
常见错误现象:
— 订单服务写入成功,库存服务因网络超时回滚,结果订单存在但库存没扣;
— 用 Spring 的 TransactionSynchronizationManager 手动传播事务上下文——这在跨进程调用中完全无效。
本质是:分布式系统没有全局锁、没有共享内存、没有统一事务协调器(除非你显式引入),所以必须换思路。
Seata AT 模式怎么落地才不翻车
Seata 是目前 Java 生态最成熟的分布式事务方案之一,AT(Automatic Transaction)模式对业务代码侵入最小,但配置和使用细节极易出错。
关键实操点:
- 必须确保每个参与服务都接入了 Seata 的
DataSourceProxy,否则 SQL 不会被解析,undo_log 表不会写入 —— 这是最常见的“事务看似生效实则没回滚”的原因; -
global_transaction_timeout默认是 60 秒,如果某个服务响应慢(比如调用第三方接口卡住),整个全局事务会直接GlobalRollback,但下游服务可能已提交,造成状态不一致; - MySQL 必须开启
binlog(log-bin=ON),且隔离级别不能是READ_UNCOMMITTED,否则 Seata 无法正确生成 undo_log; - 避免在事务分支中做非幂等操作(如发短信、调外部 HTTP),因为回滚重试时会重复执行。
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
}
@Primary
@Bean("dataSource")
public DataSource dataSource(DruidDataSource druidDataSource) {
// 必须包装成 DataSourceProxy,否则 AT 不生效
return new DataSourceProxy(druidDataSource);
}
}
什么时候该放弃分布式事务,改用最终一致性
不是所有跨服务操作都值得上 Seata 或 TCC。当业务容忍短时间不一致(比如“下单成功后 2 秒内库存才扣减”),用消息队列 + 本地事务表更稳、更轻量。
典型场景:
- 用户注册后发欢迎邮件(失败可告警重试,不阻塞主流程);
- 订单创建后更新推荐系统画像(延迟几秒无感知);
- 积分变动与优惠券发放耦合度低,且各自有补偿机制。
核心做法:
— 在订单服务本地事务中,把“扣库存”事件写入 transaction_message 表(和订单同库);
— 启动定时任务或监听 binlog,把消息投递到 RocketMQ/Kafka;
— 库存服务消费消息,执行扣减,并记录处理状态;
— 若消费失败,靠消息重试 + 死信队列 + 人工干预兜底。
比 Seata 少了 TC 组件运维成本,也避开了长事务锁表、全局事务超时等问题。
面试常问的 TCC 和 Saga 怎么快速区分
两者都是柔性事务模型,但设计哲学完全不同:
-
TCC要求业务自己实现Try/Confirm/Cancel三个接口,比如“冻结余额”、“确认扣款”、“解冻余额”。它强调资源预留,适合资金类强一致场景,但开发成本高、空回滚/悬挂问题必须手动处理; -
Saga是基于事件驱动的长事务,每个步骤发布一个完成事件,下游监听并触发下一步(正向链路),同时定义对应的补偿动作(逆向链路)。它不要求预留资源,更适合流程长、参与方多、异构系统混搭的场景(如电商履约:下单 → 仓配 → 物流 → 签收)。
一句话判断:
— 如果你能提前锁定资源(如库存、额度),且愿意为每个接口补三个方法,选 TCC;
— 如果流程不可逆、各环节由不同团队维护、部分服务还是 PHP/Go 写的,就用 Saga(比如通过 MQ + 补偿任务表实现)。
真正容易被忽略的是:TCC 的 Confirm 和 Cancel 必须设计成幂等,且 Try 阶段不能做真实变更(否则 Cancel 就没法干净撤回)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











