spring 批处理 - 如何避免重新加载(写入)之前加载的数据 运行

spring batch - how to avoid re-loading(writing) data that was loaded in the previous run

我有一个基本的 spring 批处理应用程序,它试图将数据从 csv 文件加载到 mysql。该程序确实在第一个 运行 期间将文件加载到数据库中。但是,当我不小心重新 运行 再次 job/app 时,它引发了主键冲突(出于正确的原因)。

避免重新加载目标系统上存在的数据的最佳方法是什么?当批处理作业被安排时,如果出于任何充分的原因,源文件自上次 运行 以来没有更改,我希望看到 0 条记录已处理消息而不是主键违规错误。希望它有意义。

更多信息: 谢谢。我可能没有理解答案。让我以更好的方式解释我的要求。我有一个文件包含来自外部数据源的数据(比如新员工数据),固定名称为 hire.csv。该文件应使用每个 运行 的增量更改进行更新。由于可能存在未删除所有加载行的手动错误,因此前 运行 的一些新员工也将出现在当前 运行 中。 itemreader 或 itemprocessor 中是否有一种机制可以跳过那些已经存在于目标数据库中的记录?我可以 "insert into tb where not in (select from tb)" 但是我不想使用的每一行都是 运行 。希望现在清楚了。再次感谢。

However when I accidently re-run the job/app again, it had thrown the primary key violation (for the right reasons). What is the best way to avoid reloading the data that is present on the target system?

您正在摄取的文件应该是一个(识别)作业参数。这样,当第一个 运行 成功时,作业实例就完成了,不能再 运行 了。这是在 Spring 批处理中为这个用例设计的:防止因错误而意外执行两次作业。

编辑: 根据评论添加更多选项

  • 如果删除文件是一个选项,那么您可以使用作业侦听器或最后一步在摄取文件后将其删除。使用此选项,您需要添加第二个标识参数(因为文件名始终为 hire.csv)以确保每个 运行 都有不同的作业实例。此选项不需要为每个 运行.

  • 设置不同的文件名
  • 如果文件可以重命名为 hire-${timestamp}.csv 并且是唯一的,那么在摄取文件并使用带有文件名的单个作业参数后删除文件就足够了

旁注:我看到有人使用业务键来识别输入文件中的记录,并使用项目处理器来查询数据库并过滤已摄取的项目.这适用于小型数据集,但由于对每个项目的额外查询,因此在大型数据集上表现不佳。