【发布时间】:2020-10-07 01:59:47
【问题描述】:
我正在处理一个项目,我们在其中定义了两个聚合:“项目”和“任务”。除了其他属性之外,该项目还具有点属性。这些点按用户定义的方式分配给任务。在用例中,用户为某些任务分配积分,但项目必须有这些积分可用。 我们目前对此建模如下:
- “task.RequestPoints(points)”,此方法将创建具有属性点和 taskId 的聚合 PointsAssignment,在其构造函数中发出 PointsAssignmentRequested 域事件。
- 下发事件的处理程序会获取与任务相关的项目和聚合PointsAssigment并调用方法“project.assignPoints(pointsAssigment, service)”,即会将PointAssignment聚合作为参数和服务传递计算任务的当前点与所需点之间的差异。 如果积分可用,项目将修改其积分属性并发出“ProjectPointsAssigned”域事件,该事件将包含 pointsAssignmentId 属性(以及其他属性)
- 最后一个事件的处理程序将获取 PointsAssingment 并确认“pointsAssigment.Confirm ()”,此聚合将发出 PointsAssigmentConfirmed 域事件
- 最后一个事件的处理程序将调出关联的任务并调用“task.AssignPoints (pointsAssignment.points)”
我的问题是:在第 2 步中传递项目方法中的聚合 PointsAssignment 是否正确?这是我发现能够关联聚合的唯一方法。 注意:我们创建了 PointsAssignment 聚合,以便在失败的情况下我可以保存错误“pointsAssignment.Reject(reasonText)”并将其显示给用户,因为我使用的是最终一致性(每个事务 1 个聚合)。
我们考虑使用流程管理器 (PointsAssingmentProcess),但同样我们需要第三个聚合 PointsAssingment 来关联此流程。
【问题讨论】:
-
您真的需要可扩展性吗?我的意思是,你能在一个 TX 中改变两个 AR 吗?如果它是具有单个服务器的中型应用程序,您并不总是需要经历最终一致性和消息传递的麻烦。
-
另外,你能不能把它简化为
project.assignPoints(taskId, amount)→PointsAssignedToTask {taskId, amount}→task.assignPoints(event.amount)?我唯一不喜欢的是不清楚你不能直接打电话给task.assignPoints(…)。也许重命名为task.acknowledgePointsAssigned(),甚至只是task.apply(event)。 -
你看我的评论了吗?
-
我会研究 sagas。
-
@plalx 在分配积分的事务中,在任务中更改了另一个属性时代,例如,名称,描述等......它是用户更改积分值的形式,名称,描述和提交
标签: domain-driven-design saga eventual-consistency domain-events