@Transactional注解加不加 rollbackFor = Exception.class 的区别
先上结论:
1. @Transactional只能回滚RuntimeException和RuntimeException下面的子类抛出的异常 不能回滚Exception异常
2. 如果需要支持回滚Exception异常请用@Transactional(rollbackFor = Exception.class)
3. 这里如果是增删改的时候我建议大家都使用@Transactional(rollbackFor = Exception.class)
1、首先我在Mysql中准备了一条数据
2、简单粗暴的开始测试了(RuntimeException异常)
2.1、我们的目的是需要把delflag修改为0 简单的准备一下sql
<update id="test">
UPDATE tbl_users set delflag='0' where account='admin'
</update>
2.2、我们先来测试一下@Transactional 代码如下 大家都知道2/0必会抛出异常
@Override
@Transactional
public Ret test(){
int i = articleMapper.test();
int a = 2/0;
if(i > 0){
ResultUtil.success();
}
return ResultUtil.error();
}
2.3、执行测试 i=1说明更新成功 别着急咱们继续断点往下面走
2.4、果然不出所料 执行到第54行的时候报错了 出现了java.lang.ArithmeticException: /by zero
2.5、细心的同学会发现ArithmeticException这个异常类是继承了RuntimeException的,而@Transactional默认回滚的的异常就是RuntimeException
2.6、我们在点进去RuntimeException这个类里面一探究竟
我们发现RuntimeException又是继承Exception的而所有的异常类基本都是继承RuntimeException包括刚才上面的java.lang.ArithmeticException异常
所以只要是RuntimeException和RuntimeException下面的子类抛出的异常 @Transactional都可以回滚的
2.7、这个时候我们去看一下数据库的值到底有没有修改成功 很显然数据是被回滚了 并没有修改成0
3、下面我们在试试@Transactional不能回滚的异常 代码如下我们直接先用try catch来捕获异常 然后在catch里面自定义抛出Exception异常
@Override
@Transactional
public Ret test() throws Exception {
int i = articleMapper.test();
try {
int a = 2 / 0;
} catch (Exception e) {
throw new Exception();
}
if (i > 0) {
ResultUtil.success();
}
return ResultUtil.error();
}
3.1、ok直接 抛出的异常是我们指定的java.lang.Exception异常 我们去看看数据库
3.2、数据库被更新成0了 说明@Transactional并不能回滚Exception异常
总结一下
@Transactional只能回滚RuntimeException和RuntimeException下面的子类抛出的异常 不能回滚Exception异常
如果需要支持回滚Exception异常请用@Transactional(rollbackFor = Exception.class)
这里如果是增删改的时候我建议大家都使用@Transactional(rollbackFor = Exception.class)
欢迎一起来学习和指导,谢谢关注!
本文来自博客园,作者:xiexie0812,转载请注明原文链接:https://www.cnblogs.com/mask-xiexie/p/16601498.html