当前版本仍在开发中,尚不被视为稳定版本。最新稳定版请使用 Spring Batch 文档 6.0.2!

防止状态持久化

默认情况下,所有 ItemReaderItemWriter 实现都会在提交之前把当前状态保存到 ExecutionContext 中。 但这并不总是你想要的行为。比如,很多开发者会通过“处理标记”让数据库 reader 具备可重复运行能力。做法是在输入数据中增加一列, 用来表示该记录是否已经被处理。当某条记录被读取(或写出)时,就把这个 processed 标记从 false 改为 true。 随后,SQL 语句就可以在 where 子句中增加一个条件,例如 where PROCESSED_IND = false,从而确保在重启时只返回尚未处理的记录。 在这种场景下,最好不要保存任何状态,例如当前行号,因为这些信息在重启时已经没有意义。正因如此,所有 reader 和 writer 都提供了 saveState 属性。

  • Java

  • XML

下面的 bean 定义展示了如何在 Java 中禁止状态持久化:

Java Configuration
@Bean
public JdbcCursorItemReader playerSummarizationSource(DataSource dataSource) {
	return new JdbcCursorItemReaderBuilder<PlayerSummary>()
				.dataSource(dataSource)
				.rowMapper(new PlayerSummaryMapper())
				.saveState(false)
				.sql("SELECT games.player_id, games.year_no, SUM(COMPLETES),"
				  + "SUM(ATTEMPTS), SUM(PASSING_YARDS), SUM(PASSING_TD),"
				  + "SUM(INTERCEPTIONS), SUM(RUSHES), SUM(RUSH_YARDS),"
				  + "SUM(RECEPTIONS), SUM(RECEPTIONS_YARDS), SUM(TOTAL_TD)"
				  + "from games, players where players.player_id ="
				  + "games.player_id group by games.player_id, games.year_no")
				.build();

}

下面的 bean 定义展示了如何在 XML 中禁止状态持久化:

XML Configuration
<bean id="playerSummarizationSource" class="org.spr...JdbcCursorItemReader">
    <property name="dataSource" ref="dataSource" />
    <property name="rowMapper">
        <bean class="org.springframework.batch.samples.PlayerSummaryMapper" />
    </property>
    <property name="saveState" value="false" />
    <property name="sql">
        <value>
            SELECT games.player_id, games.year_no, SUM(COMPLETES),
            SUM(ATTEMPTS), SUM(PASSING_YARDS), SUM(PASSING_TD),
            SUM(INTERCEPTIONS), SUM(RUSHES), SUM(RUSH_YARDS),
            SUM(RECEPTIONS), SUM(RECEPTIONS_YARDS), SUM(TOTAL_TD)
            from games, players where players.player_id =
            games.player_id group by games.player_id, games.year_no
        </value>
    </property>
</bean>

上面配置的 ItemReader 不会在它参与的任何一次执行中向 ExecutionContext 写入条目。