1. 失效原因

1.1. Bean 是否是代理对象⭐️🔴

1.2. 入口函数是否是 public 的⭐️🔴

image.png

AbstractFallbackTransactionAttributeSource#computeTransactionAttribute

image.png

allowPublicMethodsOnly 方法由子类 AnnotationTransactionAttributeSource 实现,该子类方法中默认是 true,所以当你加了事务注解的方法不是 public 时,该方法直接返回 null

1.3. 是否支持事务

数据库是否支持事务 (Mysql 的 Mylsam 不支持事务),行锁才支持事务

1.4. 切点是否配置正确

1.5. 内部方法间调用导致事务失效⭐️🔴

1.5.1. 解决方案 1

再声明一个 service,自己注入自己,将内部调用改为外部调用

1.5.2. 解决方案 2

因为 this 不是代理对象,可以配置 expose-proxy=”true”,就可以通过 AopContext.currentProxy() 获取到当前类的代理对象。

1
SpuInfoService proxy = (SpuInfoService) AopContext.currentProxy();

1.5.3. 解决方案 3

使用编程式事务

image.png

1.6. 异常类型是否配置正确 (回滚策略)⭐️🔴

image.png

关键字和接口-7、Throwable

默认只支持非受检 (检查) 异常:RuntimeException 和 Error,不支持受检 (检查) 异常。

想要支持检查异常需要配置 rollbackFor
@Transactional(rollbackFor = Exception.class)

image.png

image.png

TransactionInterceptor#invoke
image.png
TransactionAspectSupport#invokeWithinTransaction
image.png
TransactionAspectSupport#completeTransactionAfterThrowing
image.png
rollbackOn(Throwable ex)
image.png
image.png

1.6.1. 为什么默认只支持非受检异常⭐️🔴

配置了这个,Exception 异常的事务,就会生效,如果没有配置则使用父类的默认配置逻辑如下:❕%%
1713-🏡⭐️◼️为什么事务回滚只支持非受检异常 ?🔜MSTM📝 因为系统重 rollbackOn 条件默认是这两种类型◼️⭐️-point-202302131713%%

DefaultTransactionAttribute
image.png

1.7. 异常被 catch 住了

代码中手动 catch 了异常,然后又未抛出来,此时事务就不生效了。
image.png

解决方法:要么不 catch 需要回滚的异常,要么 catch 之后再抛出,要么手动回滚

1.7.1. 解决方案 1

catch 之后往外抛异常
image.png

1.7.2. 解决方案 2

catch 之后,设置手动回滚
image.png

1.8. SpringMVC

Spring-4、SpringMVC

2. 实战经验

3. 参考与感谢

https://www.jb51.net/article/214403.htm

https://ost.51cto.com/posts/13157