1

我在 DDD 中使用最终一致性和域事件,我遇到了以下问题。

使用工厂创建域对象时,我可以生成 GUID,但无法获取 DB 生成的 ID 以返回有效 ID 作为响应的一部分。

在同一事务中持久化域对象并避免等待最终一致性时,是否有可能以及如何使用域事件获取数据库生成的 ID。

数据库生成的 ID 是同一聚合根和存储库的一部分。

4

2 回答 2

0

我见过的似乎效果最好的方法是让 SQL db 服务器带有一个完整的 IDENTITY 列来发出 ID,这在实际创建实体之前需要执行(例如,在创建命令时,如果你也重新使用 CQRS)。这种方法实际上很容易实现和支持,并且只需要在您的数据库中添加一个表(甚至不需要)。这不是一种不常见的做法,并且使您的 bc 从拥有 ID 生成逻辑的责任中解脱出来(在某些情况下,这可能非常有用)。

注意:与我们软件世界中的所有事物一样,这需要权衡取舍:

  1. 它可以保证排序,但是如果具有一个 id 的某个操作失败并且您重试您的操作,则id 的序列可能会有间隙。仅当您关心订购实体的创建时,这才重要:)
  2. 这会影响性能,因为您有一个瓶颈(老实说,您需要有一个非常大的流量才能成为一个明显的问题,所以我不会认为这是一个大问题)
  3. 在某些情况下,这可能是一个安全问题,具体取决于此 id 的使用方式。

我不得不说以上所有观点都很小众,我不认为这真的是一个问题。

有关此实践的参考和更多信息,您可以阅读 Twitter 的 Snowflake 项目。Snowflake 生成顺序的类似 guid 的 64 位整数 id,但很多(如果不是全部)原则仍然适用于这种情况。在很多讨论 Snowflake 的文章中有很多关于这种做法的信息和最佳实践。

问候, 萨瓦斯

于 2017-08-10T13:11:52.460 回答
0

我认为你可以有两种选择:

  1. 如果对象创建成本不高,则不必最终保持一致。在 DB 中创建对象并返回生成的 ID。

  2. 如果代价高昂,请将对象创建分解为小单元。根对象应该简单快速地创建,以便在数据库中持久化并返回生成的 ID。让通过事件/消息最终一致地创建其他子对象/聚合。

于 2017-08-10T13:00:49.537 回答