6

恐怕我已经知道答案了,但我希望有人可以提供以前没有找到的替代解决方案。与往常一样,根据有效聚合设计进行 DDD比我想象的要困难,但这是我的场景。

  • 我们有两个 AR,User 和 RoleGroup
  • 一个用户可以被授予一个特定的角色组,从而获得该角色组中角色(一个集合值对象)提供的权限。角色组的身份作为另一个 VA 保存在用户 AR 中。
  • 当从系统中删除 RoleGroup 时,我们会引发一个域事件,处理程序使用该事件来查找引用该 RoleGroup 的所有用户并删除该引用。相应的投影反规范化器将使用相同的事件来更新用户的有效角色。这是授予该用户的各个角色和所有授予 RoleGroup 的角色的组合。
  • 这不一定是事务性的(因为它最终可以是一致的)。
  • 我们通过 Jonathan Oliver 的 EventStore 3.0 以及 Lokad.CQRS 和 NCQRS 中的元素来使用 Event Sourcing。

因此,理论上,当一个请求(它是一个 ASP.NET MVC 应用程序)正在执行上述场景时,另一个请求可能会将相同的 RoleGroup 授予用户。如果在上述域事件处理程序扫描与该角色组相关的用户之后发生这种情况,则该请求将完成。此时,您有一个已删除的角色组(尽管不是物理删除)和一个仍持有该角色组身份的用户。

你如何防止这种情况发生?我们目前正在考虑将用户的身份授予该 RoleGroup AR 的特定 RoleGroup 一部分,以便删除 RoleGroup 并将其授予用户将导致乐观并发冲突。但不知何故,这感觉不是正确的解决方案。

4

3 回答 3

1

这类似于如何解决唯一性约束。

假设有一个具有 SERIAL 行为的角色组和用户的投影。当角色组被归档(即它们不能再被使用)时,位于投影顶部的反应位可以通知所有已被授予该角色组的用户他们不再是它的一部分。当同时将此归档角色组授予用户(或一组)时,可以利用投影的连续性质来告诉该用户他们不再是该组的一部分。

综上所述,这只是家务。只有当角色组和用户被使用时,正确的视图才是重要的。由于我假设角色组将带有 IsArchived 位,因此我可以安全地将它们过滤掉,而不必担心一些悬而未决的边缘情况,我们仍然必须证明它必须以自动方式解决。

顺便说一句,扫描事件日志也会揭示这种情况,即是否有任何用户授予了在该时间点之前(或在该时间点附近)存档的角色组?管理员可以通过向用户聚合发出补偿命令来解决此问题。

“视情况而定” TM

编辑:我已经为这个问题提供了一个技术解决方案。我会鼓励其他读者探索建模和解决这类问题的不同方法。有时,甚至在大多数情况下,答案根本不是技术性的。YMMV。

于 2012-11-29T14:01:49.353 回答
1

为什么要向 User 聚合添加 RoleGroup 引用?使用此信息的用户是否有任何不变量?

我想这可以通过 RoleGroup 聚合将 RoleGroup 授予用户来更简单地建模,发出类似于 RoleGroupGrantedToUser 事件的东西。当 RoleGroup 被移除时,它会发出 RoleGroupRemoved 事件。在此事件之后,角色组不再接受新用户。

于 2012-11-29T13:15:08.073 回答
0

为了防止这种情况,您可以使其具有事务性,即无法通过某种锁定机制将已删除的 RoleGroup 授予用户。但这只会使事情复杂化,正如您所指出的,这不是必需的。

当您将 RoleGroup 分配给用户时,我想您也有一个类似的投影反规范化器来更新用户的有效角色。您可以在那里检查授予的 RoleGroup 是否仍然存在,如果不存在,则从用户中删除引用。那么用户的有效角色最终应该是一致的。

于 2012-11-29T13:07:09.587 回答