Spring事务异常回滚

默认 spring 事务只在发生未被捕获的 RuntimeExcetpion 时才会回滚。

  • 类似这样的方法不会回滚:
    if(userSave) {
        try {
            userDao.save(user);
            userCapabilityQuotaDao.save(capabilityQuota);
        } catch (Exception e) {
            logger.info("能力开通接口,开户异常,异常信息:" + e);
        }
    }
  • 下面的方法会回滚:
    if(userSave) {
        try {
            userDao.save(user);
            userCapabilityQuotaDao.save(capabilityQuota);
        } catch (Exception e) {
            logger.info("能力开通接口,开户异常,异常信息:" + e);
            throw new RuntimeException();
        }
    }

或者

    if(userSave) {
        try {
            userDao.save(user);
            userCapabilityQuotaDao.save(capabilityQuota);
        } catch (Exception e) {
            logger.info("能力开通接口,开户异常,异常信息:" + e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

spring aop 异常捕获原理

被拦截的方法需显式抛出异常,并不能经任何处理,这样 aop 代理才能捕获到方法的异常,才能进行回滚,默认情况下 aop 只捕获 RuntimeException 的异常,但可以通过配置来捕获特定的异常并回滚。

换句话说在 service 的方法中不使用 try{}catch{} 或者在 catch 中最后加上 throw new RuntimeExcetpion();,这样程序异常时才能被 aop 捕获进而回滚。

解决方案:

  1. 例如:service 层处理事务,那么 service 中的方法中不做异常捕获,或者在 catch 语句中最后增加 throw new RuntimeException() 语句,以便让 aop 捕获异常再去回滚,并且在 service 上层(controller 层)要继续捕获这个异常并处理。
  2. 在 service 层方法的 catch 语句中增加:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

手动回滚,这样上层就无需去处理异常。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,785评论 18 399
  • 事务回滚机制 默认spring事务只在发生未被捕获的 runtimeexcetpion时才回滚。 如果不写rool...
    嘻洋洋阅读 434评论 0 0
  • 嗨喽,你好,我是瑞瑞。今天和你分享眼保健操,一起来保护心灵的窗口~眼睛。 眼保健操必须经常操练,做到动作准确, 并...
    Ai静儿读易经的女子阅读 49,444评论 0 3
  • 欢迎您关注西安竹梅清酒业有限公司 西安国际港务区白马酒城实业有限公司是我公司总部,它集规模,实力,资源,品质于一体...
    木子初心阅读 437评论 0 0
  • 文/不够床长和床不够长 必须设立一个尺度, 一张铁床。 在不够床长和床不够长之间, 拉伸一切的不存在, 砍去无二的...
    白衣卿相lhr阅读 249评论 0 4