Axon MongoDB-message ='E11000重复键错误集合uniqueAggregateIndex dup键:{:“ 101”,:0}

时间:2019-05-25 12:34:24

标签: java mongodb spring-boot axon

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

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

下面是用例

  1. 用户创建了自己的个人资料(总计ID:101) 在mongodb(CreateEvent)中已保存了101个聚合ID。
  2. 用户已更新了他的个人资料信息, 所以我们想将UpdateEvent存储在mongo db(事件存储)

    但是要低于例外

    13:52:49.643 [http-nio-7030-exec-3]错误oaccC [。[。[。[dispatcherServlet]-Servlet [dispatcherServlet]的Servlet.service()在具有路径[]的上下文中引发了异常[请求处理失败;嵌套异常为org.axonframework.commandhandling.model.ConcurrencyException:根源已插入序列[0]处的集合[101]事件] com.mongodb.MongoBulkWriteException:服务器127.0.0.1:27017上的批量写入操作错误。写入错误:[BulkWriteError {index = 0,代码= 11000,消息=“ E11000重复键错误集合:mytest.domainevents索引:uniqueAggregateIndex dup键:{:“ 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

{     “ aggregateIdentifier”:1     “ sequenceNumber”: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 个答案:

答案 0 :(得分:1)

Axon使用该索引来确保在聚合上没有并发操作。毕竟,聚合是一个一致性边界,并且所有状态更改都应该是原子性的且高度一致。

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

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

相关问题