spring-boot - 如何在 axon 中实现读(查询)模型和写(命令)模型之间的完全一致性
问题描述
我有 2 个 spring-boot 服务充当命令和查询,如下所示。
- Command-Service:负责处理命令、事件、维护聚合状态并将数据存储到数据库中。
- Query-Service:负责处理查询以从数据库中获取数据。
请注意,这两个服务共享相同的 axon-server 实例和相同的数据库(在本例中为 ElsaticSearch)。
我的 UI 的设计方式是,当用户提交表单以创建数据时,会发生一个 ajax 调用,然后按以下顺序执行 2 个 rest 调用:
- 第一个调用是一个 post 请求,它发送到 Command-Service,执行如下:
- 使用 formdata 创建一个 CreateDataCommand 对象并触发如下:
org.axonframework.commandhandling.gateway.CommandGateway.sendAndWait(CreateDataCommand);
- CreateDataCommand 在触发 DataCreatedEvent 的聚合中处理:
@CommandHandler private DataAggregate(CreateDataCommand createDataCommand ) { AggregateLifecycle.apply(new DataCreatedEvent ()); }
- DataCreatedEvent 在 2 个地方处理,
- 在聚合本身中,聚合更新它的状态:
@EventSourcingHandler private void on(AppCreatedEvent appCreatedEvent) { // updated aggregate's state }
- 在 Projection 中,将数据保存到数据库中。
@EventHandler private void on(AppCreatedEvent appCreatedEvent) { // Saves data to database. }
- 成功执行上述操作后,ajax 立即向 Query-Service 发送 get 请求,执行如下:
- 触发 GetDataQuery 查询,如下所示:
org.axonframework.queryhandling.QueryGateway.query(GetDataQuery, ResponseType);
- GetDataQuery 被处理以从数据库中获取数据,如下所示:
@QueryHandler List<Data> getData(GetDataQuery getDataQuery){ // hits the databse and returns data. }
- 触发 GetDataQuery 查询,如下所示:
问题:即使数据通过 Command-Service 保存到数据库中,对 Query-Service 的调用也会被触发并且它总是返回空列表。在第二次调用之后,它会返回正确的数据。发生这种情况是因为 Query-Service 在 Command-Service 完成在数据库中创建数据之前命中数据库。
ajax脚本:
$.ajax({
type: "POST",
url: "directs to Command-Service to save data",
data: formData,
contentType: false,
processData: false,
cache: false,
timeout: 60000,
enctype: "multipart/form-data",
success: data => {
setTimeout(() => location.replace("url of query-service"), 1000);
}
});
有人可以帮助我实现完全一致性或找到一种方法来消除由于上述现象而发生的不一致。
解决方案
推荐阅读
- sqlite - Computing Balance Sheet
- windows - 'IAsyncOperation<>' Xamarin 表单
- r - 目前有没有办法使用生存包中的 tt() 函数来评估比例风险?
- c# - 如何使用 Microsoft.Graph C# API 请求增量
- python - 类型错误:无法将 datetime.datetime 与 datetime.date 进行比较
- mysql - 如何处理 BIG(16GB + 或 100M+ 行)文件并导入 MySQL 数据库
- reactjs - Reactjs JSX 在 GKE 下无法渲染
- kotlin - Kotlin:String 类型的 ArrayList:应用程序在通过赋值初始化元素时崩溃
- javascript - ASP.NET - 未捕获的 SyntaxError:无法在模块外使用 import 语句
- java - 什么语义/语法规则决定何时用“then”开始 CompletableFuture 方法名称?