1 事务@Transactional注意点
1- 方法必须是public
2- 杜绝方法的自调用,自调用事务不会生效
2 自调用事务失效场景一
@Service
public class DmzService {
public void saveAB(A a, B b) { saveA(a);
saveB(b);
}
@Transactional
public void saveA(A a) { dao.saveA(a);
}
@Transactional
public void saveB(B b){ dao.saveB(a);
} }
saveAB
方法上没有
@Transactional
,相当于代理类直接调用了目标类中的方法。当然没有事务啦
实际上我们在调用
saveA
跟
saveB
时调用的是目标类中的方法
3 事务的原理
我们知道Spring中事务的实现是依赖于 AOP
的,当容器在创建
dmzService
这个Bean时,发现这个类中存在了被 @Transactional
标注的方法(修饰符为public)那么就需要为这个类创建一个代理对象并放入到容器中,
只有使用这个代理对象的方法,事务才会生效。
4 自调用事务失效场景二
当我们调用save时候,我们以为的流程是这样的
但是,实际流程是这样的:
**由于saveB方法实际上是由dmzService也就是目标类自己调用的,
所以在saveB方法的前后并不会执行事务的相关操 作。
这也是自调用带来问题的根本原因:
「自调用时,调用的是目标类中的方法而不是代理类中的方法」**
5 解决自调用事务的实效
5-1 自己注入自己
5-2 利用AopContext
6 事务的回滚
默认情况下,@Transactional只对 RuntimeException
或者
Error
才会回滚。
当抛出检查异常,不会回滚。
如果想要检查异常也回滚,需要
@Transactional(rollbackFor = Exception.class)