有同学遇到设置了事务,但是也报出了错误,但是一致未生效的问题,事务没有回滚,rollbackFor也设置成了捕捉全部报错Exception,那么这是怎么回事呢,其实原因很简单
首先我们要知道,事务的回滚是通过捕捉到错误了才执行的,如果本身没有报错是肯定不会进行回滚的。但还有一种情况,是大家比较容易忽略的,比如如下的一段代码,你觉得保存数据的操作会回滚吗?
@Transactional(rollbackFor = Exception.class)public R save2(UserVO userVO) {User user = new User();// 拷贝属性BeanUtils.copyProperties(userVO, user);try {// 保存数据库saveUser(user);// 除数为0,将会报错int i = 1 / 0;} catch (Exception e) {e.printStackTrace();return R.fail("操作失败");}return R.success("操作成功");}
答案是不会,为什么呢?因为你并没有将错误抛出,而是选择了catch,也就是自己处理报错,因此@Transactional
自然捕捉不到报错,也就不会进行回滚了
我们可以更简单的将try,catch去除掉,让@Transactional
捕捉到错误,定义一个全局的错误拦截器处理报错返回即可。
@Transactional(rollbackFor = Exception.class)public R save2(UserVO userVO) {User user = new User();// 拷贝属性BeanUtils.copyProperties(userVO, user);// 保存数据库saveUser(user);// 除数为0,将会报错int i = 1 / 0;return R.success("操作成功");}
当然,如果你实在需要手动的try,catch,可能你还需要在catch里实现一些自定义的操作, 那么这时候怎么办呢?
@Transactional
也提供了手动进行事务回滚的方法:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
于是我们的代码就可以调整为
@Transactional(rollbackFor = Exception.class)public R save2(UserVO userVO) {User user = new User();// 拷贝属性BeanUtils.copyProperties(userVO, user);try {// 保存数据库saveUser(user);// 除数为0,将会报错int i = 1 / 0;} catch (Exception e) {TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();e.printStackTrace();return R.fail("操作失败");}return R.success("操作成功");}
@Transactional
@Transactional
上一篇:09说说乐观锁和悲观锁
下一篇:android ,共享内存