域驱动设计 – 偶尔连接的CQRS系统
问题:
两名员工(A& B)同时离线,同时编辑客户#123,说版本#20,同时离线继续进行更改…… 场景: 1 – 两名员工编辑客户#123并更改一个或多个相同的属性. 2 – 两名员工编辑客户#123但不要做出相同的更改(他们互相交叉而不接触). ……然后他们都回到网上,第一名员工A追加,从而将客户更改为版本#21,然后将员工B更改为版本#20 问题: 我们在方案1中保留了哪些变化? 我们可以在方案2中进行合并吗? 语境: 1 – CQRS事件采购风格系统 2 – 使用事件源Db作为队列 3 – 读模型的最终一致性 4 – RESTful API 编辑-1:到目前为止基于答案的澄清: 为了执行精细的粒度合并,我需要为一个表单中的每个字段设置一个命令? 在上面,ChangeName,ChangeSupplier,ChangeDescription等的细粒度命令,每个都有自己的时间戳,允许在事件A& A中进行自动合并. B都更新了ChangedName? 编辑-2:根据特定事件存储的使用进行跟进: 好像我会利用@GetEventStore来保持我的事件流的持久性. 他们使用乐观并发如下: >流中的每个事件将流版本增加1 > -1指定流不应该已存在 >如果未指定ES预期版本,则禁用乐观并发控制 解决方法
如果我正确理解你的设计图片,那么偶尔连接的用户将命令排队,即改变请求,并且当用户重新连接排队的命令时一起发送;只有一个数据库权限(命令处理程序查询加载其最新版本的aggretates);只有视图模型才会同步到客户端.
在此设置中,方案2通过您的设计轻松自动合并,如果您明智地选择命令,请阅读:使它们细化:对于每个可能的更改,请选择一个命令.然后,在重新连接客户端时,命令以任何顺序处理,但由于它们只影响析取字段,所以没有问题: >客户是在20号. 在场景1中,通过此设置,两个员工都将覆盖其他员工的更改: >客户是在20号. 如果B在A之前上线,则反之亦然: >客户是在20号. 有两种方法可以启用冲突检测: >检查命令的创建日期(即,员工修改的时间)是否在客户的最后修改日期之后.这将禁用方案2的自动合并功能,但会针对并发编辑提供完整的冲突检测. 两者都易于通过事件源实现(因为事件流中的各个事件的时间戳可能是已知的). 至于你的问题“我们在方案1中保留了哪些变化?” – 这取决于您的业务领域及其要求. 编辑-1:回答澄清问题: 是的,对于可以单独更改的每个字段(或字段组),您将需要一个命令. 关于你的模型:你所展示的是典型的“CRUD”UI,即多个表单字段,例如一个“保存”按钮. CQRS通常并且自然地与“基于任务”的UI组合,其中将显示状态字段(只读),并且如果用户想要改变状态,则单击,例如,“更改”状态“按钮,打开对话框/新窗口或其他UI元素,可以更改状态(在基于Web的系统中,就地编辑也很常见).如果您正在执行“基于任务”的UI,其中每个任务仅影响所有字段的一小部分,那么ChangeName,ChangeSupplier等的细粒度命令是很自然的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |