@Transactional总结

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
,相当于代理类直接调用了目标类中的方法。当然没有事务啦

image
实际上我们在调用
saveA

saveB
时调用的是目标类中的方法

3 事务的原理

我们知道Spring中事务的实现是依赖于 AOP
的,当容器在创建
dmzService
这个Bean时,发现这个类中存在了被 @Transactional
标注的方法(修饰符为public)那么就需要为这个类创建一个代理对象并放入到容器中,
只有使用这个代理对象的方法,事务才会生效。

4 自调用事务失效场景二

image

当我们调用save时候,我们以为的流程是这样的
image

但是,实际流程是这样的:

image

**由于saveB方法实际上是由dmzService也就是目标类自己调用的,
所以在saveB方法的前后并不会执行事务的相关操 作。

这也是自调用带来问题的根本原因:
「自调用时,调用的是目标类中的方法而不是代理类中的方法」**

5 解决自调用事务的实效

5-1 自己注入自己

image

5-2 利用AopContext

image

image

6 事务的回滚

默认情况下,@Transactional只对 RuntimeException
或者
Error
才会回滚。
当抛出检查异常,不会回滚。

如果想要检查异常也回滚,需要

@Transactional(rollbackFor = Exception.class)

image

posted @ 2021-12-13 21:23  姚狗蛋  阅读(26)  评论(0编辑  收藏  举报