如何在 Spring 批处理中重复一个步骤

Posted

技术标签:

【中文标题】如何在 Spring 批处理中重复一个步骤【英文标题】:How to repeat a step in Spring batch 【发布时间】:2019-12-05 23:49:55 【问题描述】:

我将 List<Merchantdetails> 传递给 MongoDb 查询。对于每个 MerchantDetails,MongoDb 中有超过 100 万条记录。所以我正在使用 Spring 数据 MongoDb 的跳过和限制。因此,我在一次查询执行中为一位商家获取了 100,000 条记录。

接下来我想在TransactionItemReader中读取这100,000条记录并处理它到ItemProcssor然后这些记录应该被传递给ItemWriter。一旦写入这 100,000 条记录。接下来的 100,000 条记录应该从 MongoDb 中为同一个商家获取。同样,它应该由阅读器读取,由处理器处理,然后由写入器写入。然后在下一次迭代中,下一个商人应该会发生类似的事情。

为了通过一次加载所有事务记录来避免 OutOfMemoryError,我正在使用它。

我正在考虑重复执行该步骤。例如,在 Step 的第一次执行中,获取了 100,000 条记录,并将其提供给阅读器,处理器对其进行处理,然后编写器将其写入。然后再次执行此步骤,并在某些上下文中维护一些跳过计数,该计数应用于跳过已获取的记录,并应获取并处理和写入接下来的 100,000 条记录。

我怎样才能达到这个要求?我是 Spring 批处理的新手。

【问题讨论】:

【参考方案1】:

您可以为此目的使用分页。 您可以在覆盖 ItemReader 类的 read() 方法时包含此内容。

示例代码

Pageable pageRequest = new PageRequest(offSet, limit);
mongoRepository.findAll(pageRequest);
++offSet;

【讨论】:

这可以使用 MongoItemReader 开箱即用 @LucaBassoRicci 我在查询中传递选择标准,因此使用 MongoTemplate 没有任何实现可以将 Pageable 作为参数的 find 方法。有没有其他方法可以在不使用 MongoRepository 的情况下实现这一点,或者如果我可以通过查询将我的选择标准传递给 findAll() ? 我已经使用步骤重复实现了它。我面临的另一个问题是,我想在同一个文件中多次写入标头(每个商家一个标头用于一组交易),当我使用 FlatFileHeaderCallback 时,只有在第一次调用 ItemWriter 时才第一次写入标头,对于下一个时间步骤正在重复,标题不会再次写入下一个商家交易的同一文件。任何帮助,我怎样才能实现它?

以上是关于如何在 Spring 批处理中重复一个步骤的主要内容,如果未能解决你的问题,请参考以下文章

Spring 事务处理

Spring Batch - 如何使用一个读取其他步骤的作者的并行步骤?

spring-batch入门

spring batch(批处理)

在最终模型中保存预处理步骤[重复]

Jenkins构建步骤无法解析批处理命令[重复]