1.在今天测试代码的正确性,遇到了事物不进行回滚操作.
例子:(伪代码)
当第二个insert的时候,第一个方法没有进行回滚.(查询数据库,数据表有产品信息)
2.查询解答:
默认情况下spring事务只在发生未被捕获的 RuntimeException时才回滚(运行时异常)
try catch这种把整个包裹起来,这种业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出,全被捕获并“吞掉”,导致spring异常抛出触发事务回滚策略失效。
3.最终解决方案:
解决方案1:
try {
spuDao.save(spuEntity);
skuDao.save(skuEntity);
} catch (Exception e) {
throw new RuntimeException();
}
解决方案2:
try {
spuDao.save(spuEntity);
skuDao.save(skuEntity);
} catch (Exception e) {
logger.info("保存接口出错:"+e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
配置来捕获特定的异常并回滚
(1)在service方法中不使用try catch,当代码运行在第二句保存时,会抛出运行时异常,这时候就会进行回滚
(2)在catch中最后加上throw new RuntimeException(),这样程序异常才能被aop捕获进而回滚
解决方案:
方案1.例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(controller)要继续捕获这个异常并处理 (现在项目的做法)
方案2.在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常