我担心我已经知道了答案,但我希望有人可以提供以前没有找到的替代解决方案。一如既往地根据Effective Aggregate Design做DDD比我想象的要困难,但这是我的情景。
因此,理论上,当一个请求(它是一个ASP.NET MVC应用程序)正在执行上述场景时,另一个请求可能会向用户授予相同的RoleGroup。如果在上述域事件处理程序扫描与该RoleGroup相关的用户之后发生这种情况,则该请求将完成。此时,您有一个已删除的RoleGroup(尽管不是物理上的)和仍然拥有该RoleGroup标识的User。
你怎么防止这种情况?我们目前正在考虑使用户的身份被授予该RoleGroup AR的特定RoleGroup部分,因此删除RoleGroup并将其授予用户将导致乐观的并发冲突。但不知何故,这不是正确的解决方案。
答案 0 :(得分:1)
为什么要向User聚合添加RoleGroup引用?用户是否有使用此信息的不变量?
我认为通过RoleGroup聚合向用户授予RoleGroup可以更加简单地建模,从而发出类似RoleGroupGrantedToUser事件的内容。删除RoleGroup后,它会发出RoleGroupRemoved事件。在此事件之后,RoleGroup不再接受新用户。
答案 1 :(得分:1)
这类似于如何解决唯一性约束。
假设有一个角色组和用户都有SERIAL行为的投影。当角色组被归档时(即它们不能再被使用),位于投影顶部的被动位可以通知已被授予所述角色组的所有用户,他们不再是其中的一部分。同时将此归档角色组授予用户(或一组)时,可以利用投影的串行性质告诉该用户他们不再是该组的成员。
所有这一切,这只是家务。只有当角色组和用户使用时,正确的视图才是重要的。由于我假设角色组将携带一个IsArchived位,我可以安全地将它们过滤掉,而不必担心一些悬空边缘情况,我们仍需要证明它必须以自动方式解决。
另外,扫描事件日志也会显示这种情况,即是否有任何用户被授予在该时间点之前(或在该时间点之前)存档的角色组?管理员可以通过向用户聚合发出补偿命令来解决此问题。
“这取决于”TM
编辑:我已经为这个问题提供了技术解决方案。我鼓励其他读者探索不同的建模方法。解决这些问题。有时,甚至大多数时候,答案根本不是技术性的。 YMMV。
答案 2 :(得分:0)
为了防止这种情况,您可以使其成为事务性的,即无法通过某种锁定机制将删除的RoleGroup授予用户。但这只会使事情复杂化,正如您所指出的那样,并不是必需的。
当您将RoleGroup分配给用户时,我想您有一个类似的投影非规范化器来更新用户的有效角色。您可以检查当时是否仍存在已授予的RoleGroup,如果不存在,则从User中删除该引用。然后,用户的有效角色最终应该是一致的。