从春季批次中的当前步骤调用上一步骤

时间:2015-10-01 18:42:22

标签: spring-batch

我需要使用Spring默认的FlatFileReader读取我们的模块相关事务表中的一个来获取记录并使用Spring FlatFileWriter来编写,这样我就无法控制这些读写器,因为它们不是自定义的。 然后第二步是使用SFTP将相同的平面文件传输到远程位置的tasklet。

但是有些时候,当Spring FlatFile读者没有获得记录时,它会生成带有标题的空文件。

所以我在第二步tasklet中检查文件的内容并检查它是否包含标题和记录,然后在该步骤中传输相同内容,否则我将插入一些默认记录,这些记录在事务中保留了一些逻辑表。插入完成后,我想从当前的tasklet步骤调用上一步,即步骤1 Spring平面文件阅读器。

请告诉我相同的内容,从当前步骤(即tasklet)调用上一步。

请查看以下示例作业配置

    <batch:step id="FlatFileStep3" next="TransmissionFlatFileStep4">
    <batch:tasklet>
        <batch:chunk reader="FlatFileReader" writer="FlatFileWriter" commit-interval="50"/> 
    </batch:tasklet>
                   </batch:step>
<batch:step id="TransmissionFlatFileStep4">
    <batch:tasklet>
        <batch:chunk ref="TransmissionFlatFileTasklet"/>    
        <batch:next on="NOT_COMPLETED" to="FlatFileStep3"/>
        <batch:next on="COMPLETED" to="UpdateTxnTableStep5"/>
    </batch:tasklet>
</batch:step>
<batch:step id="UpdateTxnTableStep5">
    <batch:tasklet>
        <batch:chunk ref="UpdateTxnTableTasklet"/>  
    </batch:tasklet>
</batch:step>

当spring批次到达TransmissionFlatFileStep4然后在TransmissionFlatFileTasklet中我有逻辑来检查文件内容。如果文件为空,那么我有插入逻辑将一些默认数据插入到我们的事务表中。然后在同一个tasklet(TransmissionFlatFileTasklet)中,我通过实现StepExecutionListener接口覆盖公共ExitStatus afterStep(StepExecution stepExecution)方法并设置自定义退出状态NOT_COMPLETED&amp;已完成 所以当状态为COMPLETED时调用UpdateTxnTableStep5以及它在NOT_COMPLETED上调用FlatFileCreationStep3所以这次平面文件将使用那些默认记录生成,但是一旦平面文件完成,它应该再次调用TransmissionFlatFileStep4,这不会发生批处理正在抛出错误:无法找到下一个状态

2 个答案:

答案 0 :(得分:1)

您是否考虑过使用5.3部分中记录的控制流程。有了它,您就可以定义一个退出代码,该代码可以表示您何时要回调到第一步,然后在第一步中执行类似的操作,可能会控制是再次完成整个过程还是结束。< / p>

正如我所想的那样:

<job id="job">
<step id="firstStep" parent="parent1">
    <next on="*" to="secondStep" />
    <end on="GOTOEND" />
</step>
<step id="secondStep" parent="parent2" next="thirdStep" />
<step id="thirdStep" parent="parent3" >
    <next on="RESEND" to="firstStep" />
    <end on="*" />
</step>

您可以切换它,但是您想要从步骤管理退出状态。

从那里,您可以通过步骤侦听器控制步骤的退出状态,该侦听器可以检查步骤上下文中的某些瞬态数据集。

另一个选择可能是使用决策者选择去哪里。我没有亲自使用这些,但根据他们可能为您工作的文档。

答案 1 :(得分:1)

除了Mark Kouba's answer之外,还有一些实施提示。

要控制tasklet的返回代码(即“next”标记中的值“on =”),您可以实现StepExecutionListener(或添加实现此类的自定义侦听器)。然后在方法afterStep中,您可以使用自己的逻辑返回自定义的exitCode:

@Override
public ExitStatus afterStep(StepExecution stepExecution) {

    if (true) // Your logic
        return new ExitStatus("GOTOEND"); // Your custom code
    else
        return null; // Inherit status from step
}

关于Decider的更多内容:这些是在步骤之间放置在您的作业定义中,并使用您自己的逻辑来确定下一步。它们的工作方式与afterStep相同:

<batch:decision decider="myDecider" id="myDecider">
    <batch:end on="GOTOEND" />
    <batch:next on="OTHER" to="OtherStep"/>
    <batch:fail on="*" />
</batch:decision>

<bean id="myDecider" class="xx.xx.xx.MyDecider"></bean>

bean的引用类需要实现JobExecutionDecider并覆盖方法decide

@Override
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {

    if (true) // Your logic 
        return new FlowExecutionStatus("GOTOEND");
    else
        return FlowExecutionStatus.FAILED;

}

此外,如果您需要控制FlatFileItemWriter的内容,则可以将属性shouldDeleteIfEmpty设置为false,以防止创建该文件。请参阅FlatFileItemWriter documentation