Spring事务传播行为
1.什么是事务传播行为
==事务传播行为是为了解决业务层方法相互调用的事务问题==
当一个事务方法被另外一个事务方法调用时,必须指定事务如何传播
1 |
|
2.REQUIRED
Spring默认的事务传播行为
如果外部方法没有开启事务的话,
Propagation.REQUIRED
修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。如果外部方法开启事务并且被
Propagation.REQUIRED
的话,所有Propagation.REQUIRED
修饰的内部方法和外部方法均属于同一事务 ,只要一个方法回滚,整个事务均回滚。
1 | //aMethod()和bMethod()使用的都是PROPAGATION_REQUIRED传播行为两者使用的就是同一个事务,只要其中一个方法回滚,整个事务均回滚。 |
aMethod()和bMethod()使用的都是PROPAGATION_REQUIRED传播行为两者使用的就是同一个事务,只要其中一个方法回滚,整个事务均回滚
3.REQUIRES_NEW
创建一个新的事务,如果当前存在事务,则把当前事务挂起。外部方法是否开启事务,Propagation.REQUIRES_NEW
修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。
1 |
|
bMethod()
使用PROPAGATION_REQUIRES_NEW
事务传播行为修饰,aMethod
还是用PROPAGATION_REQUIRED
修饰的话。如果aMethod()
发生异常回滚,bMethod()
不会跟着回滚,因为 bMethod()
开启了独立的事务。但是,如果 bMethod()
抛出了未被捕获的异常并且这个异常满足事务回滚规则的话,aMethod()
同样也会回滚,因为这个异常被 aMethod()
的事务管理机制检测到了。
3.NESTED
如果当前存在事务,就在嵌套事务内执行;如果当前没有事务,就执行与TransactionDefinition.PROPAGATION_REQUIRED
类似的操作。也就是说:
- 在外部方法开启事务的情况下,在内部开启一个新的事务,作为嵌套事务存在。
- 如果外部方法无事务,则单独开启一个事务,与
PROPAGATION_REQUIRED
类似。
1 |
|
如果 bMethod()
回滚的话,aMethod()
不会回滚。如果 aMethod()
回滚的话,bMethod()
会回滚。
4.MANDATORY
如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
5.SUPPORTS
如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
6.NOT_SUPPORTED
以非事务方式运行,如果当前存在事务,则把当前事务挂起。
7.NEVER
以非事务方式运行,如果当前存在事务,则抛出异常。
8.事务失效
SpringAop自调用
当一个方法被标记了@Transactional
注解的时候,Spring 事务管理器只会在被其他类方法调用的时候生效,而不会在一个类中方法调用生效。
1 | //事务失效 |
@Transactional修饰的方法不是public方法
设置的 @Transactional
的 rollbackFor
和 propagation
属性不正确,事务失效不回滚
被 @Transactional
注解的方法所在的类没有被 Spring 管理
底层使用的数据库不支持支持事务机制