Spring Batch:重新运行作业后重复行

时间:2015-01-07 10:37:50

标签: spring-batch

我们的Spring Batch应用程序在重新启动失败的作业后,再次处理相同的记录,导致重复的行,我们想要了解如何避免这种情况。

启动批处理作业的Spring Integration轮询器配置为每隔几个小时运行一次。当它第二次运行时,作业参数将是相同的,但如果前一次运行失败(例如,由于DataTruncation异常),Spring Batch将不会抱怨作业已经完成。

在失败时,已经处理了数十万条记录并将其从源表复制到目标表。当作业在后续运行时,相同的行将被复制到目标表,从而导致重复。因此,似乎作业没有恢复,而是从一开始就重新开始。

Spring Batch数据库是Derby(基于文件),这是在应用程序启动时设置的,并且在实际应用程序的重新启动之间不会保持状态(因为可以使用相同的参数再次运行作业)。但是,在一个应用程序运行中,状态得以维护。例如,如果作业成功完成,则下次轮询器运行异常将被抛出,因为作业(带有这些参数)已经完成。

我们的工作定义如下:

<batch:job id="publisherJob" >
   <batch:step id="step1">
      <batch:tasklet >
    <batch:chunk reader="itemReader" processor="itemProcessor"
              writer="itemWriter" commit-interval="${...}" />
        </batch:tasklet>

        <batch:listeners>
        ...
        </batch:listeners>
</batch:job>

<bean id="itemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
   <property name="dataSource" ref="dataSource" />
   <property name="sql" value="select ${...} from ${...} where ${...}" />
   <property name="rowMapper" ref="rowMapper" />
</bean>

WHERE子句包含ORDER BY。

我们的理解是,Spring Batch将保留处理失败的状态并从该点开始(如果源表中的错误已得到修复),从而防止重复行。必须为此配置什么?

由于

1 个答案:

答案 0 :(得分:1)

Spring Batch维护状态,因为它记住处理了多少记录,而不是具体记录了哪些记录。因此,您可以保证项目的顺序在运行期间可以重现,这样,如果我们在运行1中处理100条记录并且失败,当我们跳过运行2中的前100条记录时,那些是要跳过的100条记录。您没有为JdbcCursorItemReader提供配置,但我的假设是您没有在SQL中使用订单。如果要重新启动,则需要某种方法来保证项目的顺序。在SQL中使用order by是实现此目的的最简单方法(如果需要,还可以使用过程指示器模式)。