当前位置: 首页 > 知识库问答 >
问题:

Spring批处理:重新运行作业后重复行

赫连鸿振
2023-03-14

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

启动批处理作业的Spring集成轮询器配置为每两个小时运行一次。第二次运行时,作业参数将相同,但如果上一次运行失败(例如,由于数据截断异常),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子句包括订货人。

我们的理解是Spring Batch将保留处理失败的状态,并从该点开始(如果源表中的错误已被修复),从而防止重复行。要发生这种情况需要配置什么?

谢谢

共有1个答案

范修伟
2023-03-14

SpringBatch维护的状态是,它会记住处理了多少条记录,而不是具体记住了哪些记录。因此,由您来保证项目的顺序在不同的运行中是可重复的,因此,如果我们在运行1中处理100条记录但失败,那么当我们在运行2中跳过前100条记录时,这些记录就是要跳过的正确的100条记录。您没有为JdbcCursorItemReader提供配置,但我假设您在SQL中没有使用order by。如果您想要可重启性,您需要某种方法来保证项目的顺序。在SQL中使用ORDERBY是实现这一点的最简单方法(如果需要的话,还可以使用流程指示符模式)。

 类似资料:
  • 我有一个spring批处理作业,从CSV文件读取并写入数据库。我想让它重新启动。例如,如果在读取文件或写入db时出现异常,导致作业失败,则应从失败的同一点/块重新开始,而不是从头开始读取整个文件。 我正在从一个endpoint触发作业启动器,并在我的控制器中配置了它。 目前,我正在通过控制器将参数(这是一个唯一的标识符/数字)传递给作业参数,以运行新的作业实例。如果作业失败,我将使用与GET请求中

  • 我正在使用spring批处理读取CSV文件并使用controller触发器将其写入DB。在启动应用程序时,在我从浏览器url中点击之前,我会在启动时看到来自阅读器的打印语句。虽然它不为我的处理器或写入器打印它,它们是在单独的类中,我已经自动连线。是因为读者是豆子吗?

  • 有人知道有没有办法在Spring重新开始吗?我希望它首先从第一步开始,然后是第二步,第三步,然后回到第一步,第二步,第三步,等等,直到满足条件。我试着用谷歌搜索,但没有找到任何具体的例子。 迄今为止的代码:

  • 问题内容: 运行main方法时,将执行作业。这样我无法弄清楚如何控制作业的执行。例如,您如何安排作业,访问作业执行或设置作业参数的方式。 我试图注册自己的JobLauncher 但是当我尝试在主要方法中使用它时: 当加载上下文时,该作业再次执行,而当我尝试手动运行它时,我得到了。有没有办法防止自动作业执行? 问题答案: 通过设置可以防止作业执行 在application.properties中。或

  • Spring批处理作业与flatfileitemreader(从csv读取)、processor(更新adwords api提要详细信息,对于csv文件中的每个记录(大约有40条记录),这一步大约需要40秒)和正在更新DB中记录的定制writer一起使用。 web.xml

  • 我按照这个示例使用Boot进行Spring批处理。 运行main方法时,作业将执行。这样我就不知道如何控制作业的执行了。例如如何排定作业、访问作业执行或设置作业参数。 我尝试注册自己的JobLauncher 但当我尝试在主法中使用时: 当加载上下文时,再次执行作业,并且尝试手动运行作业时得到。有没有办法防止自动执行作业?