domain-driven-design - 我如何使用 Axon 使用相同的第一个 InitAvailableQuantityCommand 重新初始化某些值?
问题描述
假设我们有股票。此库存应保留产品 ID 和可用数量。该库存的用户可以频繁更新(InitAvailableQuantityCommand)可用数量。如果某些产品已售出,我们的系统将收到已售出事件(DecreaseAvailableQuantityCommand),并且已售出产品的可用数量应该减少。
它适用于下面的聚合,直到一件事,如果我再次尝试使用 InitAvailableQuantityCommand 重新初始化库存,该事件将被忽略并引发错误
已插入序列 [0] 处的聚合 [3333] 事件”
我试图达到的目标如下:
- InitAvailableQuantityCommand (productId = 1, 数量 = 10)
- DecreaseAvailableQuantityCommand(productId = 1,数量 = 1)
- DecreaseAvailableQuantityCommand(productId = 1,数量 = 1)
- 现在我们还有 8 种可用产品。
- 并且此时用户将使用 productId 1 的 20 个可用产品重新初始化库存。用户将发送一个新的 InitAvailableQuantityCommand (productId = 1, quantity = 20),此时它失败并且不起作用。
我错了什么?
谢谢。
@NoArgsConstructor
@Aggregate
@Data
public class AvailableQuantityAggregate {
private String partnerId;
private String productId;
@AggregateIdentifier
private String productVariationId;
private int quantity;
@CommandHandler
public AvailableQuantityAggregate(InitAvailableQuantityCommand cmd) {
final ApplyMore apply = AggregateLifecycle.apply(AvailableQuantityInitializedEvent.builder()
.partnerId(cmd.getPartnerId())
.productId(cmd.getProductId())
.productVariationId(cmd.getProductVariationId())
.quantity(cmd.getQuantity())
.build());
}
@CommandHandler
public void handle(DecreaseAvailableQuantityCommand cmd) {
AggregateLifecycle.apply(AvailableQuantityDecreasedEvent.builder()
.productVariationId(cmd.getProductVariationId())
.quantity(cmd.getQuantity())
.build());
}
@EventSourcingHandler
protected void on(AvailableQuantityInitializedEvent event) {
this.productVariationId = event.getProductVariationId();
this.partnerId = event.getPartnerId();
this.productId = event.getProductId();
this.quantity = event.getQuantity();
}
@EventSourcingHandler
protected void on(AvailableQuantityDecreasedEvent event) {
this.quantity = this.quantity-event.getQuantity();
}
}
解决方案
实例化InitAvailableQuantityCommand
一个聚合。聚合本质上具有同一性。因此,聚合标识符用于表示它是谁/是什么。当您在 Axon 中默认使用事件源时,事件存储将确保您不会添加具有相同聚合 id 和序列号的事件。但是,当您InitAvailableQuantityCommand
第二次发布时,您是在告诉框架发布具有相同聚合 id 和序列号的事件。
因此,您的建模解决方案应该有所不同。实例化聚合的操作(又名命令)与重置聚合不同。因此,我建议添加一个不同的命令来将您的聚合重置为其初始值。
推荐阅读
- c++ - 如何在没有复制构造函数的情况下为地图设置值?
- python - interrows 问题 - 运行 PyLyrics 时输出 NaN
- c# - 如何使用自签名客户端证书修复 asp.net core 3.1 中的 RevocationStatusUnknown
- swift - 我想在我的图像 OCR 上应用谷歌翻译应用画笔效果
- python - Pandas-遍历数据框列并连接包含列表的相应行值
- javascript - 是否有任何功能可以检测站点域已更改?
- catboost - 使用 onnx 保存 catboost 模型时,可以保存和使用客户参数吗?
- ruby-on-rails - Rails - 由于 spring gem 无法运行 rails 服务器
- c# - 两种不同类型的字典并转换为 JSON
- java - 错误:不兼容的类型:int 无法转换为 String