Domain Driven Design CQRS 模式下单保存按钮的命令触发与一致性问题
单Save按钮触发多命令的实现方案
- 优先采用聚合级命令封装方案:不用把细粒度的
changeDetails、addSomething、removeSomething对应的原子命令直接暴露给前端,直接针对这个汇总编辑页面的业务场景,在应用层封装一个独立的聚合更新命令,比如UpdateXXXFullInfoCommand,命令参数承载页面所有可修改字段。在该命令的Handler内部,按业务规则依次调用领域对象对应的修改方法,所有领域校验通过后,在同一个事务内完成数据持久化即可。这是最符合DDD聚合设计原则的实现,同一个聚合的修改本来就应该落在同一个事务边界内,拆成多个独立命令属于过度设计。 - 如果确实需要保留细粒度命令,可在前端做变更Diff:用户点击Save时,前端对比页面初始数据和修改后的数据,自动生成对应的命令列表:基础信息有修改就生成
changeDetails命令、新增了子项就生成addSomething命令、删除了子项就生成removeSomething命令,把整批命令一次性提交给后端即可。
批量命令执行的一致性保障
会不会出现数据不一致完全取决于你怎么设计执行逻辑:
- 如果整批命令都针对同一个聚合实例:把所有命令的执行过程包裹在同一个本地事务中即可,任意一个命令执行失败,整个事务直接回滚,所有修改都不会生效,不会出现部分更新的问题。
- 如果整批命令涉及多个不同聚合的修改:不要用本地事务做强一致,改用Saga事务编排实现最终一致性:把整批命令按依赖顺序编排执行流程,每个命令执行成功就推进到下一个,一旦某个命令执行失败,就按预设的补偿规则回滚之前已经执行成功的操作,最终保证所有数据状态一致。
额外提醒:DDD的命令设计本来就不需要和领域模型的方法一一对应,命令是对用户操作意图的封装,完全可以根据实际的前端交互场景调整粒度,强行对齐细粒度领域方法反而会增加不必要的复杂度。
内容的提问来源于stack exchange,提问作者Ngọc Nguyễn
相关产品推荐
相关产品推荐

