带有 MongoDB 和事务的 Spring 批处理

Posted

技术标签:

【中文标题】带有 MongoDB 和事务的 Spring 批处理【英文标题】:Spring batch with MongoDB and transactions 【发布时间】:2021-05-31 04:29:05 【问题描述】:

我有一个带有两个数据库的 Spring Batch 应用程序:一个用于 Spring Batch 元数据的 SQL DB,另一个是存储所有业务数据的 MongoDB。关系数据库仍然使用DataSourceTransactionManager。 但是我不认为 Mongo 写入是在带有回滚的活动事务中完成的。这是MongoItemWriter上official Spring Batch documentation的摘录:

使用 Spring Data 的 MongoOperations 实现写入 MongoDB 存储的 ItemWriter 实现。由于 MongoDB 不是事务性存储,因此会尽最大努力在最后一刻持久化写入的数据,但仍遵守作业状态合同。如果写入过程中发生错误,则不会尝试回滚。

但是现在情况已经不同了; MongoDB introduced ACID transactions in version 4. 如何将事务添加到我的写入中?当我使用ItemWriterAdapter 时,我可以在我的服务方法上使用@Transactional。但是还是不知道怎么处理MongoItemWriter...这里的正确配置是什么?谢谢。

【问题讨论】:

【参考方案1】:

我有一个带有两个数据库的 Spring Batch 应用程序:一个用于 Spring Batch 元数据的 SQL DB,另一个是存储所有业务数据的 MongoDB。

我邀请您查看以下帖子以了解此设计选择的含义:

How to java-configure separate datasources for spring batch data and business data? Should I even do it? How does Spring Batch transaction management work?

在您的情况下,您有一个跨两个数据源的分布式事务:

作业存储库的 SQL 数据源,由 DataSourceTransactionManager 管理 MongoDB 用于您的步骤(使用MongoItemWriter),由MongoTransactionManager 管理

如果您希望在同一个分布式事务的范围内提交/回滚技术元数据和业务数据,您需要使用协调DataSourceTransactionManagerMongoTransactionManagerJtaTransactionManager。您可以在此处找到有关此问题的一些资源:https://***.com/a/56547839/5019386。

顺便说一句,在 Spring Batch 中有一个使用 MongoDB 作为作业存储库的功能请求:https://github.com/spring-projects/spring-batch/issues/877。实现此功能后,您可以将业务数据和技术元数据存储在同一个数据源中(因此不再需要分布式事务),并且您可以将相同的 MongoTransactionManager 用于作业存储库和您的步骤.

【讨论】:

感谢您抽出宝贵时间,@Mahmoud。你对这个特性的 ETA 有一个粗略的估计吗?谢谢。 否,但我们可能会考虑在下一个主要版本 v5 中使用它(我们尚未确定日期)。但与此同时,您应该能够使用 JTA 事务管理器实现您想要的。

以上是关于带有 MongoDB 和事务的 Spring 批处理的主要内容,如果未能解决你的问题,请参考以下文章

带有悲观锁的过程中的Spring JPA事务提交

Spring框架——批处理(batch)和事务(Transaction)

如何使用 Spring 和 Hibernate 为 Web 应用程序和批处理作业设置事务

如何使用 Spring 和 Hibernate 为 Web 应用程序和批处理作业设置事务

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

如何更改spring批处理事务隔离级别