SpringBoot中try/catch异常并回滚事务(自动回滚/手动回滚/部分回滚)

业务需求

实现一个异步任务,先记录任务状态为执行中,直接返回结果给前端,然后异步执行任务的业务逻辑,如果执行过程中抛出异常,捕获异常并更新任务状态为执行失败;若未抛出异常,更新任务状态为执行成功

异常处理

1、自动回滚

    @Transactional(rollbackFor = Exception.class)
    public void asyncJob() throws Exception {
        success();
        //假如exception这个操作数据库的方法会抛出异常,方法success()对数据库的操作会回滚
        exception();
    }

2、手动回滚(进行try/catch,回滚并抛出)

    @Transactional(rollbackFor = Exception.class)
    public void asyncJob() {
        success();
        try {
            exception();
        } catch (Exception e) {
            e.printStackTrace();
            //手工回滚异常
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

3、回滚部分异常

    @Transactional(rollbackFor = Exception.class)
    public void asyncJob() {
        success();
        //设置回滚点,只回滚以下异常
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        try {
            exception();
        } catch (Exception e) {
            e.printStackTrace();
            //手工回滚异常,回滚到savePoint
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
        }
    }

伪代码

    @Autowired
    private AsyncJobService asyncJobService;

    @Transactional(rollbackFor = Exception.class)
    public Boolean executeJob() {
        checkProcessJob();//检查是否存在流程中的任务
        Job job = new Job();
        job.setStatus(StatusEnum.IN_PROGRESS);//设置任务状态为执行中
        jobMapper.insert(job);

        asyncJobService.asyncExecute(job);//异步执行任务
        return true;
    }
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void asyncExecute(Job job) {
        //设置回滚点,只回滚以下异常
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        try {
            exception();
        } catch (Exception e) {
            //手工回滚异常,回滚到savePoint
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            log.error("异步执行任务失败,{}", e.getMessage());
            job.setStatus(StatusEnum.FAIL);//设置任务状态为执行失败
            jobMapper.updateById(job);
            return;
        }
        job.setStatus(StatusEnum.SUCCESS);//设置任务状态为执行成功
        jobMapper.updateById(job);
    }
发布了177 篇原创文章 · 获赞 407 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_40378034/article/details/104012100