【问题标题】:Is it possible to update in database in jdbccursoritemreader是否可以在 jdbccursoritemreader 中更新数据库
【发布时间】:2015-06-04 14:53:41
【问题描述】:

我正在使用 Spring 批处理 JDBCCursorItemReader 从表中读取一组数据。读取数据后,spring batch 将处理块中的每一行(读取器、处理器、写入器)。现在我想更新/删除我的读者获取的那些记录,以避免被同一作业的另一个实例重新处理。有人可以告诉我如何在阅读器中做到这一点吗?

谢谢

【问题讨论】:

  • 你不要在阅读器中这样做,那只是为了阅读......你想在你的编写器中这样做,也许是一个自定义块侦听器。
  • 但是我想在我的阅读器获取这些记录后立即更新/删除,而不是在处理后,因为编写器只有在处理后才会执行,我可以为此使用编写器吗?
  • 当操作失败时你会怎么做?您的记录已被标记为已处理,但尚未处理……那又如何?此外,它仅在事务提交后才可见,并且您不希望每条记录都有一个事务,因为这会影响您的性能。不允许作业的多个实例不是更容易解决吗?
  • 感谢回复。根据我的要求,我需要运行同一作业的多个实例,所以我想将输入行更新为中间状态,其他实例不会处理。如果步骤/作业失败,我将更新回初始状态,以便其他实例重新处理。如果我使用块侦听器,我可以让 itemreader 一次读取所有记录以更新到中间状态吗?
  • 为什么要同时运行同一个作业的多个实例来处理相同的数据?有更好的方法可以在单个作业实例中协调数据的并行处理,以防止此类问题(分区等)。

标签: spring spring-batch


【解决方案1】:

正如已经指出的那样,这可能是一个糟糕的设计想法。但是,如果您确定这是您想要做的,

创建一个两步作业,
步骤 a,提交间隔为 1
阅读记录
用当前作业执行 id 写入更新的记录
步骤 b
读取作业执行id为当前作业执行id的记录
根据需要处理和更新

注意事项

  1. 由于 cmets 中所述的原因,我不推荐这种方法
  2. 提交间隔为 1 会在性能方面扼杀你的表现,因此如果曾经使用过这种方法,则应该仅用于低容量作业。

【讨论】:

  • 无法理解您的意思是两步流程?我想在第一次执行 itemreader 时将那些由我的 itemreader 获取的记录更新为类似于处理的记录,因此它不会被其他实例选择。就像我执行 'select * from tablea where status="not processed"' 时一样,将给出 100 行(所有这些行都需要在处理开始之前更新为处理),同时如果再向 tablea 插入 100 行status="not processed" 表的第二个实例应该只选择 100 条记录,而不是在第一个实例仍在运行时选择 200 或 100+。
  • 我了解您在寻找什么。您可以在可用的项目编写器中执行此操作。您将需要编写一个客户项目编写器。或者你可以写一个两步的工作。作业中的步骤 1 读取记录并将记录标记为已读以进行处理。第 2 步仅读取那些标记为准备处理的记录,然后处理这些记录
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-02
  • 1970-01-01
  • 2014-04-29
  • 2011-04-16
  • 2021-09-16
  • 2017-08-07
相关资源
最近更新 更多