2014-12-30 43 views
0

我试着弹出批处理。通过ItemReader和ItemWriter运行作业时,我见过很多示例。如果一项工作没有错误地运行,没有问题。 但是我还没有找到如何处理一个作业失败后,处理大量的记录状态。弹出批处理状态,当步骤失败

我的场景很简单。从xml文件(ItemReader)读取记录并调用外部系统进行存储(ItemWriter)。那么如果外部系统在进程中间不可用并且一段时间后作业状态设置为FAILED,会发生什么情况?如果我在外部系统启动并运行的第二天再次手动重新启动作业,那么我将得到以前加载的记录的重复项。

在某些方面,我必须有用于跳过已经加载的记录的信息。 我试图通过ExecutionContext存储游标,但是当我重新启动作业时,我得到一个新的JOB_EXECUTION_ID,并且游标数据丢失,因为BATCH_STEP_EXECUTION_CONTEXT.SHORT_CONTEXT中有一个新行。重新启动时,BATCH_STEP_EXECUTION.COMMIT_COUNT和BATCH_STEP_EXECUTION.READ_COUNT也会重置。

我使用JobOperator重新启动作业: jobOperator.restart(jobExecutionId);

有没有办法重新启动一项工作,而无需获得新的jobExecutionId或交替的方式来获取失败的工作状态。如果有人发现(可以提供)示例包含状态和错误处理,我会很高兴。

一个替代解决方案当然是创建我自己的表来保存已处理记录的轨迹,但我真的希望框架有一个机制。否则,我不会用春天的批次来说明这个想法。

问候 垫

回答

2

一个主要特点Spring Batch的提供是在作业库作业的状态的持久性。当作业失败时,重新启动时,默认行为是在失败步骤重新启动作业(跳过已成功完成的步骤)。在基于块的步骤中,我们的大多数读者(包括StaxEventItemReader)存储在作业存储库中已处理的记录(具体在ExecutionContext内)。默认情况下,当基于块的步骤失败时,将在上一次失败的块上重新启动,跳过成功处理的块。

这一切的一个例子是,如果你有一个三步工作:

<job id="job1"> 
    <step id="step1" next="step2"> 
     <tasklet> 
      <chunk reader="reader1" writer="writer1" commit-interval="10"/> 
     </tasklet> 
    </step> 
    <step id="step2" next="step3"> 
     <tasklet> 
      <chunk reader="reader2" writer="writer2" commit-interval="10"/> 
     </tasklet> 
    </step> 
    <step id="step3"> 
     <tasklet> 
      <chunk reader="reader3" writer="writer3" commit-interval="10"/> 
     </tasklet> 
    </step> 
</job> 

而且我们说这个作业完成第一步,那么第二步有1000条记录进行处理,但在创纪录的507块失败由记录500-510组成的记录将回滚,该作业将被标记为失败。该作业的重新启动将跳过step1,在步骤2中跳过记录1-499并从步骤2的记录500开始(假设您正在使用有状态项读取器)。

对于重新启动时的jobExecutionId,Spring Batch具有作业实例(逻辑运行)和作业执行(物理运行)的概念。对于每天运行的工作,逻辑运行将是星期一运行,星期二运行等。其中每个工作将包括它们自己的JobInstance。如果工作成功,JobInstance将最终只有一个JobExecution与它关联。如果失败并重新运行,则会为每次重新启动作业创建一个新的JobExecution

您可以在Spring Batch的文档中读取一般和具体方案的更多有关错误处理在这里找到:http://docs.spring.io/spring-batch/trunk/reference/html/index.html

+0

谢谢支持!我的问题更多地是关于在一个块内保持状态。我的工作只有一个步骤,如下所示: 阅读器读取xml并且编写器更新外部资源。块内是否仍然支持spring-batch状态(如果我重新启动作业,如果在前一天处理过程中作业失败,则跳过一些xml记录)?也许替代方案是有两个步骤没有任何块呢? – Mats

+0

然而,我使用'JobExecution'作为例子,'StepExecution'(和它的相关的'ExecutionContext')在一个步骤中保持状态,包括由块组成的块。在每个块提交之后,步骤的状态(包括已读取的记录数等)将保存到作业存储库中,以便发生故障时,已重新处理的记录将被跳过。 –

相关问题