命令在CQ [R] S模型中应该有多精细?


17

我正在考虑一个项目,我们基于WCF的SOA的迁移部分转移到服务总线模型(可能nServiceBus),并使用一些基本的发布-订阅实现命令查询分离

我对SOA甚至服务总线模型都不陌生,但我承认直到最近,我的“分离”概念还仅限于常规数据库镜像和复制。尽管如此,我还是被这个想法所吸引,因为它似乎提供了最终一致的系统的所有好处,同时又避免了许多明显的缺点(最明显的是缺乏适当的交易支持)。

我从Udi Dahan那里读了很多关于该主题的书,他基本上 ESB体系结构专家(至少在Microsoft世界中是这样),但是他说的一件事确实让我感到困惑:

当我们获得更大的实体并在其上具有更多字段时,我们也将有更多的参与者与这些相同的实体一起工作,并且在任何给定时间某些事物触及它们的某些属性的可能性更高,从而增加了并发冲突的数量。

[...]

CQRS的核心要素是重新考虑用户界面的设计,以使我们能够掌握用户的意图,因此,使客户成为首选对象对于用户而言是与指示客户已搬家或已获得客户不同的工作单元。已婚。如上所述,使用类似Excel的UI进行数据更改不会捕获意图。

-Udi Dahan,澄清了CQRS

从引文中描述的角度来看,很难与这种逻辑争论。但这似乎与SOA背道而驰。SOA(实际上是一般的服务)应该处理粗粒度的消息,以便最大程度地减少网络震颤,这还有许多其他好处。

我认识到,当您拥有分布良好,消息队列良好且没有RPC负担的系统时,网络颤抖就不再是问题,但是完全消除该问题似乎并不明智。Udi几乎似乎在说,每个属性更改(即字段更新)都应该是它自己的命令,很难想象一个用户可能像传统上那样经常更新数百或数千个组合的实体和属性。网络服务。

给定良好的高度参数化查询,表值参数或对临时表的批量插入,SQL Server中的一次批处理更新可能花费一秒钟的时间;一次处理所有这些更新很慢,很,而且OLTP数据库硬件是所有扩展/扩展中最昂贵的。

有什么办法可以调和这些相互竞争的问题?我是否以错误的方式思考?这个问题在CQS / ESB领域是否有众所周知的解决方案?

如果不是,那么如何确定命令中粒度的“正确级别”呢?是否有一些“标准”可以用作起点(类似于数据库中的3NF),并且仅在仔细分析表明潜在的显着性能优势时才偏离标准?

或者,尽管各种专家表达了一些强烈的意见,这可能只是其中的一种吗?

Answers:


7

关于“每个属性都在变化”的主题

我想你错过了重点。乌迪·达汉(Udi Dahan)先生说您应该以命令的形式把握用户的意图。最终用户担心能够指示客户已搬家。根据命令的上下文,该命令可能包含客户标识,新地址(分为街道,街道编号,邮政编码等),还可以选择新电话号码(移动时并不罕见-所有这些手机可能较少) 。那不是一个属性。更好的问题是“我如何设计命令?”。您从行为的角度设计它们。最终用户试图完成的每个用例,流程和任务,都将通过一个或多个命令捕获。这些命令附带的数据是自然而然的,因为您开始更详细地进行推理。需要注意的是被解释为“可能表明您需要拆分命令。我希望您永远不会在命令粒度方面找到该标准。很好的问题!


这个定义对我来说仍然很武断。CSR的概念模型可能会将首选状态和军事状态汇总在一起,就像将地址和邮政编码汇总在一起一样。我的意思不是split断头发,在我看来,为了真正了解它们是否具有不同的行为,您必须能够预测下游影响,并且可以预言ESB,CQS和pub /这说明您不应该知道或关心下游发生的事情。谢谢您的回答,我很感激,尽管到目前为止我还不能说感到启发……
Aaronaught 2011年

@Aaronaught:定义任意的。命令的粒度应适合您的特定情况。没有一个适合所有人的尺码。有几种准则,例如匹配命令以使用UI中可用的用例或任务或动作-另一准则是优先使用粒度更小的命令,而不是粒度较小的命令(尤其是Yves表示警惕被解释为逻辑控制流的数据)-但没有硬性规定。是否存在“一个用户可能更新数百或数千个组合的实体和属性”的实际情况?
quentin-starin 2011年

这就是重点!别在一起 按行为划分!不要将数据放入与命令/最终用户意图不一致的命令中。这与下游系统无关。
伊夫·雷恩豪特

@qes:在我们的系统中,有很多这样的场景,这是非常真实且非常必要的。为了尽可能简单地陈述它,他们需要修改整个数据序列,而这些序列仅作为序列才有意义。当然,他们通常不会逐条记录这些更改,而是将某种算法应用于其中的大部分内容,然后修复一些异常。也许这并不是CQS的合适选择,但是这个决定只是我更广泛的问题的一部分。
亚伦诺特,2011年

1
@qes:很公平,这本身就是一个答案。我当然明白的逻辑运算的概念(这是现有的服务建模方式),我想我只是一直担心,CQS似乎改变周围的几个规则如何你应该定义的操作。“传统” SOA似乎从最粗略的定义开始,并在必要时向下移动抽象阶梯。到目前为止,我对CQS的理解似乎表明相反,它从可能的最细粒度的定义开始,如果看起来像RPC或控制流,则从抽象开始。
亚伦诺特2011年

2

Udi试图传达的信息是CQRS不仅仅是CRUD。为什么创建此记录?我为什么要更改此记录?为什么将其删除/标记为已删除?

命令应与用户对系统进行的操作/用例相对应,并表达操作的意图,而不仅仅是说要更改此操作。另外,它看起来似乎更细,但可能比第一次出现时粗糙得多。例如,升级到金牌状态可能涉及对几个属性的更改,并且许多其他聚合甚至可能响应并响应相应事件而更改。

CQRS是关于在服务层中捕获业务语言的,因此UI不必担心当我进行金牌状态升级或运输被承运人标记为无法交付或员工已晋升时会发生什么情况给技术小组的经理。从技术上讲,我现在正在谈论事件源,但您会感到不解。有更多不同的消息,但是它们不一定比标准CUD具有更好的粒度。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.