我想实现一个可以跳过异常并正确回滚事务的小任务,但我看不到实现这两件事的方法。
我的 tasklet 从构造函数中填充的 id 队列中读取。在执行方法的每次调用中,都会处理一个 id,这取决于队列是否仍有要处理的元素,或者没有返回RepeatStatus.FINISHED或RepeatStatus.CONTINUABLE。我使用的是 tasklet 而不是块,因为每个元素的处理都相当复杂,并且意味着执行多个查询,实例化许多对象,这些对象稍后都会写入数据库。
主要问题是如果我定义一个 try/catch 块来包装实现,我可以毫无问题地跳过异常,并且仍然能够使用队列中的下一个元素重新执行 tasklet,但问题是所有内容都保存在数据库。另一方面,即使一个元素的处理正确完成而没有问题,如果提交由于某种原因而失败,因为错误发生在我的代码无法控制的范围内,我的代码和 tasklet 不会捕获到异常执行完成,不能跳过并继续队列的下一个元素。
这是我的 tasklet 的简化架构:
public MyTasklet() {
elementsIds = myRepo.findProcessableElements();
}
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
Long id = elementsIds.remove();
try {
// Business logic
} catch (Exception e) {
// is there a way to tell the framework to rollback ?
LOG.error("error ...", e);
}
if (elementsIds.isEmpty()) {
return RepeatStatus.FINISHED;
} else {
return RepeatStatus.CONTINUABLE;
}
}
有没有办法通过 tasklet 实现这两个要求:
- 如果在执行方法的实现中捕获到异常,则能够告诉框架回滚事务
- 如果提交失败,继续执行(连续调用)tasklet