Spring 批处理:重用现有服务作为 reader

Spring Batch: reuse existing service as a reader

我想重用现有的事务性分页服务 class,它使用 JPA 从数据库中检索项目,在 Spring 批处理作业中作为 reader。我想这样做而不是直接使用 JpaPagingItemReader,主要是因为 JPA 查询构建起来更复杂,而且服务已经提供了这个功能。

我的问题是,在通过此服务开发 Spring 批处理适配器时,我应该考虑哪些事项。尽管参考文档 http://docs.spring.io/spring-batch/trunk/reference/html/readersAndWriters.html#pagingItemReaders 有一个关于重用现有服务的部分,但它没有说明任何关于使用此类事务服务的限制(如果有的话)。

现在,我查看了 JpaPagingItemReader 作为构建 reader 的示例,我提出了几个问题,但我在文档或 Whosebug 上找不到答案,尽管这post 有帮助。

我首先注意到的是 JpaPagingItemReader 使用了一个新事务来读取一页数据。上面的post表示需要这个新的交易"so that features like retry and skip can be correctly performed."。我还发现这篇文章与 https://blog.codecentric.de/en/2012/03/transactions-in-spring-batch-part-3-skip-and-retry/ 相关,上面写着 "when a skippable exception occurs during reading, we just increase the skip count and keep the exception for a later call on the onSkipInRead method of the SkipListener, if configured. There’s no rollback"。所以我假设 reader 必须读取新事务中的记录,这样如果在处理块开始时事务开始回滚,那么 reader 不受影响.我想知道这是否属实,在这种情况下我的适配器是否应该创建一个新事务,调用该事务内的服务,然后提交该事务,类似于 JpaPagingItemReader 的操作方式。如果这是真的,我想知道为什么框架没有提供任何模板来创建事务,将实际调用委托给服务以检索数据,然后提交事务。

您好, 克里斯蒂

从reader的角度来看,确实没有什么可担心的。您可以在我们的 JmsItemReader 中看到,它显然适用于交易商店,我们没有在 ItemReader 本身内采取任何额外的预防措施。

真正重要的是如何配置步骤。配置步骤时,您需要将 reader 标记为事务性,以便 Spring 批处理正确处理回滚。当 Spring 批量读取容错步骤中的项目时,默认行为是缓冲它们,以便它们不会在失败时重新读取(重试、跳过等)。但是,由于从事务存储中读取的项目与事务相关联(因此在回滚发生时会重置),因此您需要告诉 Spring Batch 在读取项目时不要缓冲这些项目。

要将 ItemReader 标记为事务性的,您需要将名称不太恰当的标志 is-reader-transactional-queue 设置为 true。您可以在此处的文档中阅读有关配置步骤和交易的更多信息:http://docs.spring.io/spring-batch/trunk/reference/html/configureStep.html