当前位置: 首页 > 知识库问答 >
问题:

带有MongoDB和事务的Spring批处理

堵泽宇
2023-03-14

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

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

然而,情况不再是这样了;MongoDB在版本4中引入了ACID事务。如何将事务添加到我的写入中?当我使用ItemWriterAdapter时,我可以在我的服务方法上使用@Transactional。但仍然不知道如何处理MongoItemWriter...这里的正确配置是什么?谢谢。

共有1个答案

蒋乐意
2023-03-14

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

我邀请您阅读以下帖子,了解这一设计选择的含义:

  • 如何为spring批处理数据和业务数据分别配置java数据源?我应该这么做吗

在您的案例中,您有一个跨两个数据源的分布式事务:

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

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

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

 类似资料:
  • 批处理配置具有spring作业,只有一个步骤 1)读取器-从csv文件读取。处理器对文件应用一些规则。Drools请运行schema-postgresql.sql来设置数据库 WRITER使用SPRING DATA JPA写入DB Writer将此称为PersonDaoImpl:

  • 嗨,我有一个非常重要的问题。我正在尝试使用reactive r2dbc创建一个批处理,并使用transactional来注释该方法。但是看起来,如果我同时使用事务性代码和批处理代码,代码就会挂起,不起作用。下面是代码

  • 我使用FlatFileItemReader创建了一个spring批处理作业,它从一个分隔文件中读取数据,然后使用JdbcBatchItemWriter写入DB。我的setp配置如下所示。 上面的配置是为每100行打开单独的事务,因此,如果在完成tasklet(步骤1)之前发生故障,则我无法恢复之前提交的行。有没有办法在一个事务中运行整个tasklet?。 另外:我使用MapJobRepositor

  • 在happy path场景中,我有一个spring批处理工作,但现在我将重点放在错误处理上。 但是,在另一个测试中,我想证明一个不可预见的数据库错误会导致作业失败。为此,我创建了一个触发器,该触发器会导致对要插入的表的插入失败。 这似乎起作用了,在writer执行之后,在事务提交期间抛出异常,并且我得到以下日志消息: 这似乎也是预期的行为。问题是,这并不能阻止工作。该步骤退出到SimplyRetr

  • 我们正在将图形ql-spqr和图形ql-spqr-Spring启动器用于一个新项目(使用Spring数据JPA,Hibernate等)。 我们有这样一个突变: 这种突变工作正常: 我忽略了变量,因为它们不重要。如果我将其更改为: 我收到LazyInitalizationException,我知道原因: 家庭团队由一个ID引用,并由加载。返回的团队只是一个Hibernate代理。这对于保存新的匹配很