目录
1. 同一类内方法调用,无论被调用的方法是否配置了事务,此事务在被调用时都将不生效。
1. 同一类内方法调用,无论被调用的方法是否配置了事务,此事务在被调用时都将不生效。
Spring的7种事务传播行为类型
1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。‘
3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
事务默认传播行为类型为:Propagation.REQUIRED
2. 在不同类
doA()调用doB()
doA():@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
1、doB():@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
没有成功插入数据,因为我们使用的是第一种传播行为PROPAGATION_REQUIRED ,doB()方法被加入到doA()的事务中,doA()执行时抛出了异常,因为doB()和doA()同属于一个事务,则执行操作被一起回滚了。其实在doB()中我们不加入注解,也等同PROPAGATION_REQUIRED的效果。
2、doB():@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
在数据库中成功插入了doB()方法中要插入的数据,而doA()中插入的数据被回滚了,这是因为我们在doB()方法中加入ROPAGATION_REQUIRES_NEW传播行为,doB()创建了属于自己的事务,挂起了doA()中的事务,所以事务B提交了,而事务A因为执行异常插入的数据被回滚了。
3、doB()@Transactional(propagation = Propagation.NOT_SUPPORTED, rollbackFor = Exception.class)
doB()方法成功插入了数据。doA()方法中插入的数据被回滚了。这是因为传播行为PROPAGATION_NOT_SUPPORTED是doB()以非事务执行的,并且提交了。所以当doA()的事务被回滚时,doB()的操作没有被回滚。
在上面的实例中,doA()和doB()在不同类,这是因为spring通过扫描所有含有注解的@Transactional的方法,使用aop形成事务增强advise。但是加入增强时是通过代理对象调用方法的形式加入的,如果将doB()方法放在doA()方法直接调用时,在调用doB()方法的时候是通过当前对象来调用doB()方法的,而不是通过代理来调用的doB()方法,这个时候doB()方法上加的事务注解就失效了不起作用。
3. 解决办法
注入本身,再去用本身调用事务方法