今天在review同事的代码时,发现他一个使用的Transactional错误的地方,大致的代码时
@XxlJob("XXXJOB")
@Transactional(rollbackFor = Exception.class)
public void XXXFun(){
// 通过查询获取数据数组 list
// 遍历 list
list.forEach(data-> {
// 生成新的数据 dataList
// 调用 insertData方法
insertData(dataList);
});
}
public void insertData(final List<XXXDO> dataList) {
// 批量插入
}
然后我就问他 为啥不是在 insertData 方法上加事务注解,这样的的好处有:
1. 事务大小变小了
2. 不同批次的数据相互之间不影响
然后他说试过在insertData加注解,但是没有生效,所以就在主方法XXXFun加注解。
我说你在同一个类里面调用方法,Transactional注解肯定失效啊,然后建议他去网上搜一下Transactional注解失效的场景有哪些。
这里 我也贴一下我知道的失效的场景:
-
@Transactional 应用在非 public 修饰的方法上
-
同一个类中方法调用,导致@Transactional失效
由于使用Spring AOP代理,只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。
比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。
3. 异常没有抛出,被你的 catch“吃了”导致@Transactional失效
4. 抛出的异常没有在rollbackFor 范围内