我们正在将CQRS与EventSourcing结合使用。
在我们的应用程序中,我们可以从ui添加资源(这是单个项目的业务术语),并且我们正在相应地发送命令以添加资源。
因此,我们在应用程序中存在x个资源,这些资源先前已添加。
现在,我们有一种特殊类型的资源(我称其为SpecialResource)。
当我们添加此SpecialResource时,需要将id与应用程序中的所有现有资源链接。
链接意味着此SpecialResource应该具有现有资源的ID(向导)列表(列表)。
解决方案,我们尝试在添加特殊资源之前获取应用程序中的所有资源ID
资源(即在触发AddSpecialResource命令之前)。
将这些列表分配给SpecialResource,然后发送AddSpecialResource命令。
但是我们不这样做,因为按照cqrs命令不应查询。
即命令不能依赖于查询,因为查询可以具有陈旧的记录。
我们如何在不查询应用程序中现有记录的情况下实现此业务场景?
最佳答案
但是我们不这样做,因为按照cqrs命令不应查询。即命令不能依赖于查询,因为查询可以具有陈旧的记录。
这不太正确。
“命令”始终运行查询。如果使用事件源,大多数情况下,您的命令都是查询-“如果允许此命令,将生成什么事件?”
这与您所描述的情况之间的区别是聚合边界,聚合边界在事件来源域中是事件流的奇特名称。处理命令时,允许聚合针对其自身的事件流(即其自身的状态)运行查询。超出范围的是其他聚合(事件流)。
实际上,这意味着(如果 SpecialResource实际上确实需要与其他资源ID保持事务一致),那么所有这些数据都必须属于同一聚合的一部分,因此也属于同一事件流的一部分,以及这一点很直截了当。
因此,如果到目前为止,您已经使用单独的流对资源进行建模,并且现在您需要SpecialResource像您所描述的那样工作,那么您将对域模型进行相当大的更改。
好消息:这可能不是您的真正要求。考虑到您到目前为止所描述的内容-如果resourceId:99652是在SpecialResource之前的一毫秒创建的,则应将其包括在SpecialResource的状态中,但是如果在之后的一毫秒创建,则应该没有。因此,如果错过了SpecialResource之前一毫秒创建的资源,对业务的成本是多少?
因为,先天,这听起来不应该太昂贵。
更常见的是,真正的需求看起来更像是“SpecialResource需要包括在营业时间之前创建的所有资源ID”,但是实际上直到营业时间结束5分钟才需要SpecialResource。换句话说,这里有一个SLA,您可以使用该SLA更好地通知您的命令。
我们如何在不查询应用程序中现有记录的情况下实现此业务场景?
扭转局面;运行查询,将查询结果(资源ID)复制到创建SpecialResource的命令中,然后调度要传递给您的域模型的命令。 CreateSpecialResource命令在其中包含正确的资源ID列表,因此聚合不必担心如何发现该信息。
关于domain-driven-design - 如何使用CQRS和事件源处理依赖于应用程序中现有记录的Command,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35098648/