提问人:alaboudi 提问时间:11/16/2023 更新时间:11/16/2023 访问量:22
是聚合类中的版本属性泄漏事件溯源详细信息
Is Version Attribute In Aggregate Class Leaking Event Sourcing Details
问:
我正在构建一个遵循干净架构方法的应用程序。它试图确保域层独立于任何基础设施层。但是我正在查看许多实现事件源聚合的示例。奇怪的是,几乎所有示例在基聚合类上都有一个属性。像这样的东西Version
abstract class Aggregate {
public ID: string;
public version: string;
// the rest
}
我看到这个属性对整个域逻辑没有价值。它存在的唯一原因是帮助解决事件溯源和事务并发原因。在我看来,这似乎是一个泄漏。但我不知道替代方案是什么。version
所以我的问题是首先验证这是一个泄漏。其次,是询问如何解决这个问题。
答:
所以我的问题是首先验证这是一个泄漏。
是的,它是。
其次,是询问如何解决这个问题。
大多数人只是忽略了它。真。
您在这里看到的是大多数人希望在写入事件流时使用乐观并发这一事实的副作用。
为此,您需要在执行数据库写入时从读取的数据库中获取一些信息,以便您能够使用 - 换句话说,类似于“比较和交换”。(有没有 git 存储库因为别人先推送而拒绝了你的推送?
因此,元数据(无论采用何种形式)都需要在执行过程中创建消息时可用,以便将更改保存到事件存储中。
(注意:这不仅仅是事件存储约束 - 如果在共享文档存储或共享关系数据库上使用开放式并发,则会遇到类似的问题。
因此,谜语就变成了:我愿意做出哪些权衡才能将我需要的信息送到我需要的地方。
其中一个权衡是:您是要每次都从实体的历史记录中构建实体的新副本,还是要重用上次使用实体时的缓存副本?
如果您要使用实体的缓存副本,则需要提供某种机制来确定您拥有的实体副本是否与您拥有的历史记录副本一致。
用另一种方式表达同样的想法:我们在记忆中的实体是唯一的“真理来源”的概念本身就是一个漏洞百出的抽象,如果我们的目标是一个可靠的系统,那么我们需要解决抽象和现实之间的差异。
解决它的第一步是评估它是否是需要解决的问题。
没有人会把奖品送给那些将领域和持久性完美地分开的实现。在模型中使用持久性元数据设计的解决方案仍然可以为客户提供价值。
但替代方案包括:
允许模型中的元数据,但只能作为不透明的令牌。域模型独立于令牌的任何特定实现,因此依赖关系图仍然指向正确的方向(即,无需修改域代码即可更改持久性)。
将元数据“保存在信封上”;不是在域对象中,而是在保存实体的缓存副本的值中。
不要缓存,每次都从头开始重新生成实体,并在本地保留元数据,直到不再需要它。
将领域行为与数据模型分开;换句话说,将您的领域逻辑实现为特征/混合的集合,并创建特定于持久性的数据模型来托管它们。
这些都不是很好 - 你放弃一些是为了得到一些。因此,您可以进行最好的交易并继续下去。
评论