service方法如果抛出Exception,事务是不会回滚的
自己写代码测试一下就知道了
@Override
public void saveExcel(List<QualityMenuText> list) throws Exception {
//先删除
log.info("批量删除");
qualityMenuTextDao.deleteQualityMenuTexts(list);
//再新增
log.info("批量新增");
qualityMenuTextDao.batchInsertQualityMenuTexts(list);
//抛出异常
throw new Exception("抛出异常");
}
也就是说,sql成功,并没有回滚
那怎么解决这个问题呢?
手动显式添加回滚异常
@Transactional(rollbackFor = Exception.class)
上面同样的代码,事务就会神奇的回滚
说白了,就是指定哪个异常类可以回滚
那什么异常会回滚?
运行时异常
哪些是运行时异常?
异常的类继承图
Java中的所有异常类都继承自Throwable
类。Throwable
有两个主要的子类:Exception
和Error
。
-
Throwable
-
Error
- VirtualMachineError
- OutOfMemoryError
- StackOverflowError
- 等等。
-
Exception
-
RuntimeException
- NullPointerException
- ArrayIndexOutOfBoundsException
- IllegalArgumentException
- ClassCastException
- 等等。
-
其他Exception(受检查异常)
- IOException
- SQLException
- FileNotFoundException
- 等等。
-
-
哪些是Exception?
那我也不可能每个方法都去手动显式指定啊?
确实不用
因为mybatis框架(dao层数据库异常)和微服务网络调用异常(springcloud feign和dubbo框架),全部都已经自动处理——所以不需要每个都手动处理
框架实现原理
说白了,就是框架已经封装了非运行时异常为运行时异常,省得你处理
比如dubbo RpcException继承了运行时异常
网络调用异常-http框架
okhttp/spring RestTemplate封装了运行时异常
okhttp功能最丰富,推荐使用
如果已经使用spring,spring RestTemplate也能满足需求,一般没有必要引入那么多框架
HttpClient没有封装运行时异常,而是Exception
自定义业务异常
一般也要继承运行时异常,避免事务失效