Configuring a Step
for Restart
在 "`Configuring and Running a Job"部分中讨论了重新启动`Job
。重新启动对步骤有许多影响,因此可能需要一些特定的配置。
Setting a Start Limit
在许多情况下,您可能需要控制 Step
可以启动的次数。例如,您可能需要配置一个特定的 Step
,使其仅运行一次,因为它会使某些资源无效,这些资源必须在再次运行之前手动修复此问题。这是在 step 级别配置的,因为不同的 step 可能有不同的要求。仅执行一次的 Step
可以作为同一个 Job
的一部分存在,而另一个 Step
可以无限运行。
- Java
-
以下代码片段展示了 Java 中启动限制配置的示例:
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.<String, String>chunk(10, transactionManager)
.reader(itemReader())
.writer(itemWriter())
.startLimit(1)
.build();
}
- XML
-
以下代码片段展示了 XML 中启动限制配置的示例:
<step id="step1">
<tasklet start-limit="1">
<chunk reader="itemReader" writer="itemWriter" commit-interval="10"/>
</tasklet>
</step>
前一个示例中显示的步骤只能运行一次。尝试再次运行它将导致抛出 StartLimitExceededException
。请注意,启动限制的默认值为 Integer.MAX_VALUE
。
Restarting a Completed Step
对于可重新启动的作业,可能存在一个或多个步骤,无论它们是否第一次成功运行,都应该始终运行。一个示例可能是验证步骤或在处理之前清理资源的 Step
。在重新启动作业的正常处理过程中,将跳过具有 COMPLETED
状态的任何步骤(这意味着它已经成功完成)。将 allow-start-if-complete
设置为 true
会替代此设置,以便始终运行该步骤。
- Java
-
以下代码片段展示了如何在 Java 中定义可重新启动的作业:
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.<String, String>chunk(10, transactionManager)
.reader(itemReader())
.writer(itemWriter())
.allowStartIfComplete(true)
.build();
}
- XML
-
以下代码片段展示了如何在 XML 中定义可重新启动的作业:
<step id="step1">
<tasklet allow-start-if-complete="true">
<chunk reader="itemReader" writer="itemWriter" commit-interval="10"/>
</tasklet>
</step>
Step
Restart Configuration Example
- Java
-
以下 Java 示例展示了如何配置作业,以便有可以重新启动的步骤:
@Bean
public Job footballJob(JobRepository jobRepository, Step playerLoad, Step gameLoad, Step playerSummarization) {
return new JobBuilder("footballJob", jobRepository)
.start(playerLoad)
.next(gameLoad)
.next(playerSummarization)
.build();
}
@Bean
public Step playerLoad(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("playerLoad", jobRepository)
.<String, String>chunk(10, transactionManager)
.reader(playerFileItemReader())
.writer(playerWriter())
.build();
}
@Bean
public Step gameLoad(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("gameLoad", jobRepository)
.allowStartIfComplete(true)
.<String, String>chunk(10, transactionManager)
.reader(gameFileItemReader())
.writer(gameWriter())
.build();
}
@Bean
public Step playerSummarization(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("playerSummarization", jobRepository)
.startLimit(2)
.<String, String>chunk(10, transactionManager)
.reader(playerSummarizationSource())
.writer(summaryWriter())
.build();
}
- XML
-
以下 XML 示例展示了如何配置作业,以便有可以重新启动的步骤:
<job id="footballJob" restartable="true">
<step id="playerload" next="gameLoad">
<tasklet>
<chunk reader="playerFileItemReader" writer="playerWriter"
commit-interval="10" />
</tasklet>
</step>
<step id="gameLoad" next="playerSummarization">
<tasklet allow-start-if-complete="true">
<chunk reader="gameFileItemReader" writer="gameWriter"
commit-interval="10"/>
</tasklet>
</step>
<step id="playerSummarization">
<tasklet start-limit="2">
<chunk reader="playerSummarizationSource" writer="summaryWriter"
commit-interval="10"/>
</tasklet>
</step>
</job>
前一个示例配置适用于加载有关足球比赛信息并进行总结的作业。它包含三个步骤:playerLoad
、gameLoad
和 playerSummarization
。playerLoad
步骤从平面文件加载球员信息,而 gameLoad
步骤对比赛执行相同操作。最后一步 playerSummarization
根据提供的比赛总结每个球员的统计数据。假设由 playerLoad
加载的文件只能加载一次,但 gameLoad
可以加载特定目录中找到的任何比赛,在成功将它们加载到数据库后将其删除。因此,playerLoad
步骤不包含任何附加配置。它可以启动任意次数,如果完成,则跳过。但是,gameLoad
步骤需要每次运行,以防自上次运行以来已添加其他文件。它将 allow-start-if-complete
设置为 true
以始终启动。(假设游戏加载到的数据库表具有进程指示器,以确保概括步骤可以正确找到新游戏)。摘要步骤是作业中最重要的一步,配置为启动限制为 2。这很有用,因为如果步骤持续失败,则会向控制作业执行的操作员返回一个新的退出代码,并且在进行人工干预之前不能再次启动。
此作业提供了此文档的示例,与 |
本部分的剩余部分描述了 footballJob
示例的三次运行的每个运行的内容。
运行 1:
-
playerLoad
成功运行并完成,将 400 名玩家添加到PLAYERS
表中。 -
gameLoad
运行并处理了价值 11 个文件的游戏数据,将其内容加载到GAMES
表中。 -
playerSummarization
开始处理并在 5 分钟后失败。
运行 2:
-
playerLoad
没有运行,因为它已经成功完成,而allow-start-if-complete
是false
(默认值)。 -
gameLoad
再次运行并处理另外 2 个文件,还将其内容加载到GAMES
表中(使用一个进程指示符表明它们尚未处理)。 -
playerSummarization
开始处理所有剩余的游戏数据(使用进程指示符进行筛选),并在 30 分钟后再次失败。
运行 3:
-
playerLoad
没有运行,因为它已经成功完成,而allow-start-if-complete
是false
(默认值)。 -
gameLoad
再次运行并处理另外 2 个文件,还将其内容加载到GAMES
表中(使用一个进程指示符表明它们尚未处理)。 -
没有启动
playerSummarization
,作业立即被中止,因为这是playerSummarization
的第三次执行,而其限制仅为 2。必须提高限制,或者必须执行Job
作为新的JobInstance
。