You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot集成Mongock启动报错:多语句事务内不允许writeConcern

问题描述

SpringBoot集成Mongock为数据库添加索引时,启动应用抛出如下异常:

Caused by: io.mongock.api.exception.MongockException: io.mongock.api.exception.MongockException: Error in method[AddIndexToCoaching.addPartialIndexToCoaching] : Command failed with error 72 (InvalidOptions): 'writeConcern is not allowed within a multi-statement transaction' on server my-mongo-clus-shard-00-02.s5go0.mongodb.net:27017. The full response is {"ok": 0.0, "errmsg": "writeConcern is not allowed within a multi-statement transaction", "code": 72, "codeName": "InvalidOptions", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1724994211, "i": 24}}, "signature": {"hash": {"$binary": {"base64": "39UxbjF63gosdF8ktyThibybXBQ=", "subType": "00"}}, "keyId": 7357981548798279686}}, "operationTime": {"$timestamp": {"t": 1724994211, "i": 24}}}
at io.mongock.driver.mongodb.springdata.v4.SpringDataMongoV4DriverBase.executeInTransaction(SpringDataMongoV4DriverBase.java:99)
at io.mongock.runner.core.executor.ChangeExecutorBase.processChangeLogInTransactionIfApplies(ChangeExecutorBase.java:147)
at io.mongock.runner.core.executor.ChangeExecutorBase.processSingleChangeLog(ChangeExecutorBase.java:119)

使用的MongoDB连接URL:

mongodb+srv://user:<password>@my-mongo-clus.s5go0.mongodb.net/dbname?retryWrites=true&w=majority

对应的ChangeUnit代码:

@ChangeUnit(id="addPartialIndexToCoaching", order = "0001", author = "user1")
@Slf4j
public class AddIndexToCoaching {

  @Execution
  public void addPartialIndexToCoaching(MongoTemplate mongoTemplate) {
    // Create the index fields and sorting
    Document indexFields = new Document()
        .append("field1", 1)
        .append("field2", 1)
        .append("field3", 1);

    // Define the partial filter expression using Criteria
    Document partialFilterExpression = Criteria.where("status").is("DRAFT").getCriteriaObject();

    // Create the IndexOptions with the partial filter expression
    IndexOptions options = new IndexOptions().partialFilterExpression(partialFilterExpression);

    // Create the index using MongoTemplate
    mongoTemplate.getCollection("mycollection").createIndex(indexFields, options);
  }

  @RollbackExecution
  @RollbackBeforeExecution
  public void rollback() {
  }
}

主应用启用的注解:

@EnableKafka
@EnableMongoRepositories(basePackages = {
    "my.backend.da.repository"})
@EnableMongoAuditing
@EnableAuthorization
@EnableAsync(proxyTargetClass = true)
@EnableScheduling
@EnableCaching
@EnableRetry
@EnableMongock
@EnableSchedulerLock(defaultLockAtMostFor = "${shedlock.defaultLockAtMostFor}")
@EnableTransactionManagement
@EnableCronMonitoring
public class App {

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}
问题原因及解决方法

核心原因

报错的本质是:Mongock默认会将ChangeUnit的执行逻辑包裹在多语句事务中,而你的MongoDB连接URL指定了w=majority的写关注,MongoDB不允许在多语句事务内显式设置writeConcern。同时,直接调用mongoTemplate.getCollection().createIndex()会绕过Spring Data的事务管理,和Mongock的事务上下文产生冲突。

解决步骤

1. 改用Spring Data规范的索引创建方式

替换直接操作Collection的代码,使用MongoTemplate.indexOps()方法创建索引,该方法能自动适配Mongock的事务上下文:

@Execution
public void addPartialIndexToCoaching(MongoTemplate mongoTemplate) {
    // 定义复合索引的字段
    IndexField field1 = IndexField.asc("field1");
    IndexField field2 = IndexField.asc("field2");
    IndexField field3 = IndexField.asc("field3");
    CompoundIndexDefinition indexDefinition = new CompoundIndexDefinition(Arrays.asList(field1, field2, field3));
    
    // 设置部分索引过滤条件
    Document partialFilter = Criteria.where("status").is("DRAFT").getCriteriaObject();
    indexDefinition.withPartialFilterExpression(partialFilter);
    
    // 确保索引存在(不存在则创建)
    mongoTemplate.indexOps("mycollection").ensureIndex(indexDefinition);
}

2. 为当前ChangeUnit禁用事务(备选方案)

如果上述方法仍未解决问题,可以直接在@ChangeUnit注解中禁用事务——因为创建索引操作本身不需要事务支持:

@ChangeUnit(id="addPartialIndexToCoaching", order = "0001", author = "user1", transactional = false)

3. 调整MongoDB连接URL(不推荐生产环境随意修改)

若业务允许,可以尝试移除URL中的&w=majority参数,但该方法会影响全局写关注级别,需谨慎评估。

内容的提问来源于stack exchange,提问作者vallish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 22:04:54