当一个事务使用 @GlobalTransactional(分布式事务),另一个使用 @Transactional(本地事务)操作同一批数据时,核心问题是 “本地事务可能绕过分布式事务的全局锁 / 协调机制,导致数据一致性被破坏”(例如本地事务修改了分布式事务未提交的数据,导致分布式事务回滚失败)。解决的核心思路是 “让本地事务感知分布式事务的存在,或通过机制限制两者的并发冲突”,具体方案如下:
一、冲突场景举例
假设:
- 分布式事务 T1(
@GlobalTransactional):执行 “扣减库存(100→90)→ 创建订单”,中途因订单失败需要回滚(库存需从 90→100)。 - 本地事务 T2(
@Transactional):在 T1 扣减库存后、回滚前,直接执行 “扣减库存(90→80)”。
此时 T1 回滚时,会基于 undo_log 生成补偿 SQL(将库存从 90→100),但实际库存已被 T2 改为 80,回滚后库存变为 100,导致数据错误(多扣的 10 未被修正)。
二、解决方案:让本地事务 “感知” 分布式事务
1. 强制本地事务通过 Seata 代理,参与全局锁竞争(推荐)
@Transactional 本地事务默认不经过 Seata 的 DataSourceProxy,因此不会申请全局锁,导致分布式事务的全局锁失效。解决方式是 让本地事务也通过 Seata 代理的数据源,即使不使用 @GlobalTransactional,也会申请全局锁,从而被分布式事务的锁阻塞。
实现步骤:
- 确保所有数据

最低0.47元/天 解锁文章

1988

被折叠的 条评论
为什么被折叠?



