一、事务的传播行为
PROPAGION_XXX :事务的传播行为
保证同一个事务中
- PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认)
- PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
- PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常
保证没有在同一个事务中
- PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
- PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
- PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
- PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行
二、@Transactional 注解失效场景(注意事项)
1、@Transactional 注解应用在非 public 修饰的方法上,导致注解失效
2、propagation 设置错误,导致注解失败
如PROPAGATION_NEVER、PROPAGATION_NOT_SUPPORTED会使当前事务无法使用,PROPAGATION_SUPPORTS不会新建事务
3、rollbackFor 设置错误,@Transactional 注解失败
在 spring 项目中, @Transactional 注解默认会回滚运行时异常及其子类,其它范围之外的异常 Spring 不会帮我们去回滚数据(如果也想要回滚,在方法或者类加上@Transactional(rollbackFor = Exception.class) 即可。
4、方法之间的互相调用导致 @Transactional 失效
(1)非事务方法调用事务方法时,事务方法的事务不会生效;
(2)同一个类里methodA调用methodB时,methodB如果隔离级别Propagation.REQUIRES_NEW,希望创建一个新事务,这时methodB的事务注解不会生效,因为没有经代理,此时methodA和B会一起处在A的事务下,代理见四
5、异常被 catch 捕获导致 @Transactional 注解失效
6、数据库引擎不支持事务
首先,mysql支持
三、事务的四大特性
- 原子性
- 一致性
- 隔离性(重要!务必好好理解!)
a.并发的事务相互独立。事务中对数据的操作彼此不可互见,除非数据已经提交后更新到库里。
b.同一事务里的操作彼此可见。如果同一事务里先插入3条数据在查询,这3条数据是可以被查到的,如果是最后统一执行数据库操作,先查后插入则查不到。
- 持久性
四、获取类的代理对象
(1)注入applicationContext,再通过applicationContext.getBean获取代理对象。
(2)AopContext.currentProxy()获取当前类的代理类对象,局限于获取当前类。
参考:【Java 基础】SpringBoot 中 @Transactional 注解的使用与实践
Spring 事务方法与非事务方法相互调用 @Transactional 注解失效分析