业务需求
实现一个异步任务,先记录任务状态为执行中,直接返回结果给前端,然后异步执行任务的业务逻辑,如果执行过程中抛出异常,捕获异常并更新任务状态为执行失败;若未抛出异常,更新任务状态为执行成功
异常处理
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);
}