首页 > 解决方案 > 在事件溯源中按属性聚合重复数据删除

问题描述

我有带有属性的聚合产品: Id、ProductName、ProductPrice 和事件:ProductCreated、ProductNameChanged、ProductPriceChanged和命令。

我将我的事件存储在EventStore中,并在执行任何命令之前构建实际的聚合状态,此外我还有此聚合的异步读取模型。

如何检查新产品名称,我的数据库没有其他同名产品(在 CreateProductCommand 或 ChangeProductName 中)?

我无法使用我的读取模型,因为它是异步的,并且我无法读取此聚合类型的所有事件并为每个产品构建实际模型,因为此操作很昂贵。

标签: validation.net-coredomain-driven-designevent-sourcing

解决方案


有一些广泛的方法(请注意,我没有直接的 .Net 或 EventStore 经验,尽管我已经在其他堆栈中开发事件源系统几年了):

  • 跟踪哪些产品名称已被声明的读取模型不应该很昂贵。因为它是异步更新的,所以在成功创建后的一段时间内,声明的名称不会传播到该读取模型。产品创建和名称更改将是一个检查读取模型并仅在检查成功时传递命令的传奇。

  • 解决这个问题的一种方法是采用最终一致性:读取模型能够在创建了两个具有相同名称的产品之后检测并开始纠正过程(例如,可以将域模型扩充为允许将一个实例标记为另一个实例的替代 ID,并自动融合它们的累积状态;或者,如果这不可能,手动标记和干预通常会起作用)。

  • 或者,如果需要更强的一致性,您可以让名称操作传奇维护它所看到的尚未传播到读取模型的名称的状态。这将为名称可以被操纵的速率设置一个上限(因为所有这些都必须通过一个过程来协调事情)

请注意,在没有计算机的情况下,必须做出相同的决定:是由一个人负责更改目录中的产品名称,还是允许多人更改名称并接受存在冲突的可能性(这意味着有一些过程来决定如果发生冲突应该做什么)。DDD 主要是关于“首先在没有计算机的情况下解决问题”,然后将该解决方案转化为使用计算机的解决方案。

如果允许它ProductName是一个聚合 ID,那么让该聚合只是从名称到产品 ID 的映射也是可行的。


推荐阅读