我在 Spring Batch 中设置了一个有点线性的作业,它由几个步骤组成。如果在任何时候有一个步骤失败,作业就会失败。
这些步骤由许多小线程组成,后面跟着一个基于 block 的步骤。即:
- 第 1 步
- 任务 1
- 第 2 步
- 任务 2
- 第 3 步
- 读者
- 处理器
- 作家
如果出现问题,显然要做的就是抛出异常。 Spring Batch 将处理这个问题并记录所有内容。这种行为(尤其是打印堆栈跟踪)是不可取的,如果作业可以正常结束并将状态设置为FAILED
,那就更好了。
Tasklet 目前直接在 StepContribution
上设置 ExitStatus
。它们也是使用流程构建的(这并不理想,但这些步骤可以不受阻碍地继续进行)。然后可以直接在 Tasklet 中处理问题。
但是,我们无法访问基于 block 的方法中的StepContribution
。我们只有 StepExecution
。使用 setExitStatus
在这里没有任何作用。
我们使用的是构建器(JobBuilerFactory
和 StepBuilderFactory
),而不是 XML 设置。
潜在的解决方案:
- 告诉或配置 Batch 如何处理异常(而不是打印堆栈跟踪)。
- 在监听器中捕获异常。不幸的是,异常在到达
@AfterStep
时已被 Spring Batch 捕获。 - 告诉步骤/作业我们不想继续(例如,在执行上下文中设置一个值或
StepContribution
的替代方案。
最佳答案
据我所知,停止作业的唯一方法是抛出异常。没有其他优雅的方式告诉 Spring Batch“这项工作已完成,它失败了,直接进入失败,不要通过 GO 等。”
虽然不是原始问题的直接解决方案,但可以使用 StepBuilder
的 .exceptionHandler()
来更好地控制您抛出的异常,例如记录它们。
public class LogAndRethrowExceptionHandler implements ExceptionHandler {
private static final Logger LOGGER = Logger.getLogger(...);
@Override
public void handleException(RepeatContext repeatContext, Throwable throwable) throws Throwable {
LOGGER.error(throwable.getMessage());
throw throwable;
}
}
理论上,这样您就可以隐藏 Spring Batch 生成的堆栈跟踪,但仍然显示错误消息。
关于java - 在基于 block 的步骤期间中止批处理作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47718393/