带有分区的Java Batch Step返回错误的batchStatus和exitStatus

时间:2018-08-16 09:22:36

标签: java spring-batch java-batch jberet

我在JDL中有一个(非常简单的)Java批处理作业,只需两步。

当步骤“下载”返回状态“已停止”时,作业应停止。 重新启动后,应该调用stop通知。

没有分区,一切正常。

无分区统计

after step=download batchStatus=COMPLETED exitStatus=STOPPED
after job=job       batchStatus=STOPPED   exitStatus=STOPPED

有了分区,我对于批处理结束出口确实感到奇怪。 如果下载步骤返回“已停止”,则作业不会停止。 即使该分区只有一个线程和一个分区。

尝试重新启动时,将引发以下错误(当然)。 JBERET000609:作业执行1已经完成,无法重新启动。

具有分区的统计信息

after step=download batchStatus=STARTED   exitStatus=null
after job=job       batchStatus=COMPLETED exitStatus=COMPLETED

工作描述

<job id="job" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0" restartable="true">
    <step id="download" next="notify">
        <batchlet ref="downloadBatchlet">
        </batchlet>
        <partition>
            <mapper ref="basicPartition" />
        </partition>
        <stop on="STOPPED" restart="notify"/>
    </step>
    <step id="notify">
        <batchlet ref="notifyBatchlet"></batchlet>
        <end on="COMPLETED"/>
    </step>
</job>

每个提示都欢迎提出建议。我想念的是什么?

无分区

在工作开始时,工作呼叫 -downloadBatchlet =>已停止 和塞子。

在重新启动作业时,调用 -notifyBatchlet =>已完成 然后结束。

具有分区

在工作开始时,工作呼叫 -downloadBatchlet =>已停止 和塞子。

重新启动作业调用 没有步骤 然后结束。

@Named
public class DownloadBatchlet extends AbstractBatchlet {
    @Override
    public String process() throws Exception {

        return BatchStatus.STOPPED.toString();
    }
    @Override
    public void stop() throws Exception {
    }
}

1 个答案:

答案 0 :(得分:2)

分区与顶级批处理/退出状态

在Java Batch中,步骤本身以及每个分区都有单独的批处理和退出状态。

由于此处的作业级别发生了“转换”(到下一步,或者您要停止该作业),因此您需要在该步骤的“顶级”设置非默认退出状态,而不仅仅是在每个分区的级别。

如果要包括对每个分区的状态做出反应的逻辑,则最好使用PartitionAnalyzer#analyzeStatus方法,该方法在每个分区终止时被调用。它在“顶层”线程上运行(PartitionReducer也是如此)。

简单的示例分析器

public class MyPartitionAnalyzer extends AbstractPartitionAnalyzer {

    @Inject
    private StepContext stepCtx;

    @Override
    public void analyzeStatus(BatchStatus batchStatus, String exitStatus) throws Exception {

        // Overrides default exit status if non-COMPLETED partition seen
        if (!exitStatus.equals(BatchStatus.COMPLETED)) {
            stepCtx.setExitStatus(exitStatus);
        }
    }
}

您可以使用想要对分区的批处理和退出状态做出反应(或不做出反应)的任何逻辑。这里的关键是分析器在顶级步骤线程上运行,因此设置了步骤状态。另一方面,该批处理程序的返回值仅设置分区级别的状态。

可以根据需要使用分析器“聚合”分区级别的状态。如果不执行任何操作,则步骤级退出状态将默认为步骤级批处理状态,因此,如果该步骤正常完成,则步骤级退出状态为COMPLETED。