Axon MongoDB - message='E11000 重复键错误集合 uniqueAggregateIndex dup key: : "101", : 0

Posted

技术标签:

【中文标题】Axon MongoDB - message=\'E11000 重复键错误集合 uniqueAggregateIndex dup key: : "101", : 0【英文标题】:Axon MongoDB - message='E11000 duplicate key error collection uniqueAggregateIndex dup key: : "101", : 0 Axon MongoDB - message='E11000 重复键错误集合 uniqueAggregateIndex dup key: : "101", : 0 【发布时间】:2019-10-11 18:39:39 【问题描述】:

在我的应用程序中,我们使用 axon 3.3.3 和 mongo db 作为事件存储

每当用户更新他的个人资料信息时,我们都会保存所有事件。

下面是用例

    用户创建了他的个人资料(聚合 ID:101) 在 mongodb(CreateEvent) 中已经保存了 101 个聚合 id。

    用户更新了他的个人资料信息, 所以我们想将 UpdateEvent 存储在 mongo db(event store)中

    但低于异常

    13:52:49.643 [http-nio-7030-exec-3] 错误 oaccC[.[.[.[dispatcherServlet] - Servlet.service() 用于路径 [] 上下文中的 servlet [dispatcherServlet] 引发异常 [请求处理失败;嵌套异常是 org.axonframework.commandhandling.model.ConcurrencyException:序列 [0] 处的聚合 [101] 的事件已插入],其根本原因 com.mongodb.MongoBulkWriteException:服务器 127.0.0.1:27017 上的批量写入操作错误。写入错误:[BulkWriteErrorindex=0, code=11000, message='E11000 duplicate key error collection: mytest.domainevents index: uniqueAggregateIndex dup key: : "101", : 0 ', details= ]。 在 com.mongodb.connection.BulkWriteBatchCombiner.getError(BulkWriteBatchCombiner.java:176) 在 com.mongodb.connection.BulkWriteBatchCombiner.throwOnError(BulkWriteBatchCombiner.java:205) 在 com.mongodb.connection.BulkWriteBatchCombiner.getResult(BulkWriteBatchCombiner.java:146) 在 com.mongodb.operation.BulkWriteBatch.getResult(BulkWriteBatch.java:227) 在 com.mongodb.operation.MixedBulkWriteOperation.executeBulkWriteBatch(MixedBulkWriteOperation.java:276)

那么我怎样才能保存更新的事件呢?

下面是mongo db中的uniqueAggregateIndex

“聚合标识符”:1, “序列号”:1

@Value("$mongo.host:127.0.0.1")
private String mongoHost;

@Value("$mongo.port:27017")
private int mongoPort;

@Value("$mongo.db:mytest")
private String mongoDB;

@Bean
public MongoSagaStore sagaStore() 
    return new MongoSagaStore(axonMongoTemplate());


@Bean
public TokenStore tokenStore(Serializer serializer) 
    return new MongoTokenStore(axonMongoTemplate(), serializer);


@Bean
public EventStorageEngine eventStorageEngine(Serializer serializer) 
    return new MongoEventStorageEngine(serializer, null, axonMongoTemplate(), new DocumentPerEventStorageStrategy());


@Bean
public MongoTemplate axonMongoTemplate() 
    return new DefaultMongoTemplate(mongo(), mongoDB);


@Bean
public MongoClient mongo() 
    MongoFactory mongoFactory = new MongoFactory();
    mongoFactory.setMongoAddresses(Collections.singletonList(new ServerAddress(mongoHost, mongoPort)));
    return mongoFactory.createMongo();

【问题讨论】:

【参考方案1】:

Axon 使用该索引来保证聚合没有并发操作。毕竟,Aggregate 是一个一致性边界,它上面的所有状态变化都应该是原子的,并且是高度一致的。

将索引更改为非唯一是一个坏主意。它只允许插入与事件存储中已有的其他事件冲突的事件。

鉴于问题似乎在序列#0,可能是您不小心将@CommandHandler 方法建模为构造函数。 Axon 通过创建一个新实例而不是尝试加载现有实例来特别对待这些命令处理程序。在您的情况下,聚合已经存在,因为已经存储了一些事件。

【讨论】:

以上是关于Axon MongoDB - message='E11000 重复键错误集合 uniqueAggregateIndex dup key: : "101", : 0的主要内容,如果未能解决你的问题,请参考以下文章

Axon Framework 扩展 - Spring AMQP

Axon Framework - Spring Boot 集成

Axon 服务器命令不包含路由键

Axon 或 Kafka 支持 CQRS/ES

带有 Axon 的 Spring Boot JPA

Axon