0

• 我们可以通过对象引用来表达两个实体之间的关联(尽管聚合根与其内部实体之间的关系也可以通过根上定义的方法来表达--> )或通过从数据库中检索相关实体的存储库. • 当通过Repository表达关系时,客户端会直接调用Repository来获取相关实体 • 如何表达关系取决于该关系是否存在SomeRootEnt.BorrowMeIntEnt(...)

保持完整性所必需的(也许是行为是否需要关联才能表达自己)

1)如果关系(比如1:*)是通过Repository表达的,那么子实体是否需要包含父实体的ID(注意:这个问题假设至少有一个父实体是根或者它们都位于同一个总计的 )?

2)不同聚合中的实体之间的关系只能用ID来表示

a) 为什么?

b)这种关系本质上不是通过Repository表达的吗?

c) 如果b)是,这也表明在大多数情况下,不同聚合中的实体之间的关联不是为了支持特定行为而必需的?如果是,为什么?

更新:

2a)

用标识引用表达关系不同于用对象引用表达关系。应该用身份表示关系的原因是为了维护事务完整性——即在任何给定事务中只会修改单个聚合。如果使用对象引用,则事务可能会影响两个聚合。

我 - 我理解你想要表达的观点,因为如果关系将用对象引用来表达,那么仅仅是因为聚合 A1(正在修改)“物理”连接到另一个聚合 A2,这意味着A1 的一部分(即 A2 <--实际上 A2 并不是 A1 的一部分,但希望您理解这一点)与其他部分不同步?!

II - 但是从概念上讲,如果我们修改A1,那么即使两者之间的关系不使用对象引用来表达,两个聚合仍然是不同步的,所以实际上,A1和A2是否有什么区别?物理连接?

III - 无论如何,为什么我们不能在这两种情况下简单地使用最终一致性

第二次更新:

原创_2)

需要明确的是,根实体(AR)之间的关系应该用身份来表示。应该禁止不同聚合中的非根实体之间的引用。

我们是否可以拥有只能从A1 非根实体A2 根实体的单向关联(即A1 中的非根实体将包含 A2 根的 ID)?

2) 一)

我。

如果使用对象引用,则事务可能会影响两个聚合。

它创造了在修改 A1 的事务中修改 A2 的可能性。通过身份引用 A2 消除了这种可能性。此外,在加载 A1 时,诸如数据库锁定之类的事情将不适用于 A2。

暂时忽略在更新 A1 时 DB 锁定不适用于 A2 的事实 - 为什么在某些情况下我们不应该允许在单个事务中同时修改 A1 和 A2?

我知道聚合定义了一致性边界,但是如果在极少数情况下我们需要 A1 和 A2 在同一个事务中同步,那么只有其他选择可能是将 A1 和 A2 转换为单个聚合,在该特定模型中可能不是合适的?!

谢谢

4

1 回答 1

1

1) 是的。例如,假设您有一个有订单的客户。要获取客户的所有订单,您可以通过订单存储库选择具有相应 CustomerId 的所有订单。

2)要清楚,根实体(AR)之间的关系应该用身份来表示。应该禁止不同聚合中的非根实体之间的引用。

2a) 用一个身份引用表达关系不同于用一个对象引用表达关系。应该用身份表示关系的原因是为了维护事务完整性——即在任何给定事务中只会修改单个聚合。如果使用对象引用,则事务可能会影响两个聚合。

2b) 是的。存储库允许遍历,身份表示关系。

2c)这是聚合的重点——它应该定义一个一致性边界。如果对聚合的更改应该影响聚合,那么这些更改应该能够以最终一致的方式应用。

更新

2a1) 它创造了在修改 A1 的事务中修改 A2 的可能性。通过身份引用 A2 消除了这种可能性。此外,在加载 A1 时,诸如数据库锁定之类的事情将不适用于 A2。

2a2) 如果修改 A1 的事务导致需要应用到 A2 的更改,这些更改最终将被同步。保持它们物理分离的原因在 2a1 中说明。

2a3) 你可以,但同样,2a1 中指定的原因解释了为什么使用身份引用更好。

更新 2

2)我想如果两个 AR 的完整性得到维护并且参考使生活变得更容易,这是可以接受的。引用本身不是问题,它可能会导致问题。

2a1) 其原因之一在于更现代的文档数据库架构。文档数据库通常只支持单个文档上的原子事务。另一个原因是两个 AR 可能存储在不同的数据库中,在这种情况下,需要分布式事务来保持一致性。但是,关系数据库当然可以锁定多个表,因此在一个事务中修改两个 AR 的情况是可能的。因此,这些限制应被理解为指导方针。如果了解所有后果并谨慎行事,则可以接受更新两个 AR。

于 2013-02-06T20:08:39.087 回答