文章目录
1. 案例引入问题
以下面2个方法为例
@Service
public class DaoService {
@Transactional
public void laoda() {
System.out.println("老大的方法");
//在老大方法里面调用小弟方法
xiaodi();
}
@Transactional
public void xiaodi() {
System.out.println("小弟的方法");
}
}
问题:什么叫传播特性?
拿上面两个方法来说,老大方法调用小弟方法,老大方法里面发生异常小弟事务怎么处理?
2. Spring的7种事务传播特性
可以分为大三类
2.1 死活不要事务
Spring总共给了7种事务的传播特性:
就是多个事务方法相互调用时,事务如何在这些方法间传播
2.1.1 PROPAGATION_NEVER
没有就非事务执行,有就抛异常
eg:老大调用小弟方法,小弟不允许有事务,当小弟发现老大有事务时,直接抛异常,我不干,没有就正常运行
2.1.2 PROPAGATION_NOT_SUPPORTED
没有就非事务执行,有就直接挂起,然后非事务执行
eg:老大调用小弟方法,小弟不允许有事务,当小弟发现老大有事务时,就将老大的事务挂起,换句话说就是老大的事务管不着小弟,小弟自己非事务运行,不受老大事务约束
2.2 事务可有可无
2.2.1 PROPAGATION_SUPPORTS
如果有事务就用,没有就非事务执行
eg: 老大调用小弟方法,小弟会去看下老大是否有事务,有就用,没有就算了,非事务运行
2.3 必须有事务
2.3.1 PROPAGATION_REQUIRED_NEW
有没有都会新建事务,如果原来有,就将原来的挂起
eg: 老大调用小弟方法,小弟方法必须要有事务,它会去看下老大有没有事务,老大有就将老大的挂起,反正不会用老大的事务,自己新建一个新的。小弟由于是一个新的事务,所以不受老大事务影响,但是如果小弟抛异常,小弟回滚,老大就要看下是否处理异常,没有处理也回滚,处理了就不会回滚;
2.3.2 PROPAGATION_NESTED
如果没有,就新建一个事务,如果有,就在当前事务中嵌套其他事务
eg:老大调用小弟方法,小弟方法必须要有事务,它会去看下老大有没有事务,有就用老大的事务,没有就自己新建一个事务,嵌套其中。当小弟发生异常,会回滚到回滚点 savepoint.,也就是嵌套事务点,外界事务此时不会回滚,除非他对异常没有进行处理,但是如果老大发生异常,由于是嵌套,小弟必然回滚。
2.3.3 PROPAGATION_REQUIRED
如果没有,就新建一个事务,如果有,就加入当前事务
eg:老大调用小弟方法,小弟方法必须要有事务,它会去看下老大有没有事务,有就用老大的事务,没有就自己新建一个事务。 如果老大有事务,此时小弟使用老大事务,他们是一个整体,要么同时成功,要么同时失败,但是如果老大没有事务,小弟自己新建了一个事务,那么即使小弟事务抛异常也不会影响老大,因为老大没事务;
2.3.4 PROPAGATION_MANDTORY
如果没有就抛异常,如果有就是使用当前事务
eg:老大调用小弟方法,小弟方法必须要有事务,它会去看下老大有没有事务,有就用老大的事务,没有就抛异常,反正自己不会去新建事务。
必须在一个事务中运行。也就是说,他只能被一个父事务调用。否则,他就要抛出异常