Spring 批处理:传播分区步骤中遇到的异常(停止作业执行)



Background

我目前有一个读取平面文件的春季批处理作业。该作业使用MultiResourcePartitioner读取已拆分为 N 个较小文件的文件的物理分区。这意味着文件的每个物理分区都将导致执行一个新的从属步骤来读取分区。

问题所在

如果读取任何物理分区时出现问题,则该从步骤的执行将失败,并且 spring batch 将记录异常。这不会影响读取文件不同物理分区的其余从属步骤的执行;但是,这不是所需的行为。我想要的是,如果读取特定物理分区时出现问题(示例:无法解析特定列),则应将异常传播到启动Job的位置,以便我可以停止任何进一步的处理。

AbstractStep 中 execute 方法的当前实现捕获Throwable并通过记录异常来抑制异常。因此,异常不会传播到启动Job的位置,并且无法停止执行剩余的从站步骤。

如何使弹簧批处理将从步骤中发生的任何异常一直传播到启动Job的位置?我想这样做,以便在处理任何分区文件时出现问题时可以停止任何进一步的处理。

如果读取任何物理分区时出现问题,则该从步骤的执行将失败,并且 spring batch 将记录异常。这不会影响读取文件不同物理分区的其余从属步骤的执行;但是,这不是所需的行为。

我认为"这不会影响剩余从属步骤的执行"这一事实期望的行为。通常,将一大块工作划分为并行执行的较小任务背后的想法是,任务应该彼此独立,一个失败不应该影响其他失败。如果存在一个逻辑要求一个任务失败以停止其他任务,则意味着任务没有很好地定义为独立的,并且在本地/远程分区步骤中执行它们首先不是合适的选择。

我想要的是,如果读取特定物理分区时出现问题(示例:无法解析特定列),则应将异常传播到启动作业的位置,以便我可以停止任何进一步的处理。

为此,您需要一个自定义PartitionHandler。这是协调工人步骤的部分。默认行为是等待所有工作人员步骤完成并聚合结果,然后再报告给主作业。自定义实现应检测任何工作器步骤的失败,并通知其他步骤停止。

此外,如果其中一个工作线程失败,则停止/失败所有工作线程的设计不适合作业重新启动。这意味着重新启动作业将重新启动所有分区,这不是分区作业的目标,首先只应重新启动失败的分区。

最新更新