ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

spring中事务失败的几种场景【经典】

spring中事务失败的几种场景【经典】

目录

一 结论

1.1 结论说明

1.2 原因

二 案例说明

2.1 A 无事务,B 有事务,A 调用 B

2.2 A 有事务,B 有事务,A 调用 B

2.3 解决办法


一 结论

1.1 结论说明

java中同一个类中A方法没有事务,B方法有事务,A调用B方法,则B方法事务失效;

若果同一个类中A方法有事务,B方法有事务,A调用B方法,则B事务失效,b隶属于A方法的事务。

✅同类内部调用:无论 A 有没有事务,调用同类的 B(带事务)→B 事务一定失效

✅跨类调用:事务正常生效

只要是同一个类内部方法调用(自调用),不管谁调谁,被调用方的 @Transactional 永远失效!

  1. A 无事务 + this 调 B(@Transactional):B 注解失效 →无事务
  2. A 有事务 + this 调 B(@Transactional):B 注解失效 → 跑在 A 事务(B 的传播属性完全无效,REQUIRES_NEW 也开不出新事务)
  3. A 有事务 + this 调 B(无注解):B 没有事务注解 → 跑在 A 事务(最正常,没有迷惑点)

1.2 原因

Spring 事务 完全依赖代理对象 生效。只有通过代理对象调用加了 @Transactional 的方法,事务才会开启。同类内部直接调用(this. 方法 ()) → 不是代理调用 → 事务直接失效。

二 案例说明

2.1 A 无事务,B 有事务,A 调用 B

结果:B 的事务失效

失效原因:A 没有事务,A 内部直接调用 B → 用的是this.B(),不是代理对象 → Spring 感知不到@Transactional→不开启事务。

2.2 A 有事务,B 有事务,A 调用 B

结果:B 的事务 失效(不会新开事务)

原因是:

A 有事务,所以A 会开启事务

但 A 内部调用 B 依然是 this.B(),不是代理调用

所以 B 上的 @Transactional 完全无效

B 会直接加入 A 的事务,自己的传播机制、隔离级别全部不生效

2.3 解决办法

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进