@Transactional 注解相信大家并不陌生,平时开发中很常用的一个注解,它能保证方法内多个数据库操作要么同时成功、要么同时失败。使用@Transactional注解时需要注意许多的细节,不然你会发现@Transactional总是莫名其妙的就失效了。
今天开发的时候遇到这样一个问题,同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。
但是同一个类中方法的内部调用是很常见的,遇到这种问题怎么处理?我们可以把代理类再次注入进来,案例如下:
除了上面的情况会造成事务的失效,例如:如果B方法内部抛了异常,而A方法此时try catch了B方法的异常,那这个事务还能正常回滚吗?答案也是不能。案例如下:
@Transactional是否有效总结
1.@Transactional 加于private方法, 无效
2.@Transactional 加于未加入接口的public方法, 再通过普通接口方法调用, 无效
3.@Transactional 加于接口方法, 无论下面调用的是private或public方法, 都有效
4.@Transactional 加于接口方法后, 被本类普通接口方法直接调用, 无效
5.@Transactional 加于接口方法后, 被本类普通接口方法通过接口调用, 有效
6.@Transactional 加于接口方法后, 被它类的接口方法调用, 有效
7.@Transactional 加于接口方法后, 被它类的私有方法调用后, 有效
总结: Transactional是否生效, 仅取决于是否加载于接口方法, 并且是否通过接口方法调用(而不是本类调用)
当我们想判断一个方法中的事务是否生效时,我们可以在方法中加入下面的代码:
TransactionSynchronizationManager.isActualTransactionActive()
当上面的方法返回值为true时表明存在事务,返回值为false时说明不存在事务。