我在 DDD 中使用最终一致性和域事件,我遇到了以下问题。
使用工厂创建域对象时,我可以生成 GUID,但无法获取 DB 生成的 ID 以返回有效 ID 作为响应的一部分。
在同一事务中持久化域对象并避免等待最终一致性时,是否有可能以及如何使用域事件获取数据库生成的 ID。
数据库生成的 ID 是同一聚合根和存储库的一部分。
我在 DDD 中使用最终一致性和域事件,我遇到了以下问题。
使用工厂创建域对象时,我可以生成 GUID,但无法获取 DB 生成的 ID 以返回有效 ID 作为响应的一部分。
在同一事务中持久化域对象并避免等待最终一致性时,是否有可能以及如何使用域事件获取数据库生成的 ID。
数据库生成的 ID 是同一聚合根和存储库的一部分。
我见过的似乎效果最好的方法是让 SQL db 服务器带有一个完整的 IDENTITY 列来发出 ID,这在实际创建实体之前需要执行(例如,在创建命令时,如果你也重新使用 CQRS)。这种方法实际上很容易实现和支持,并且只需要在您的数据库中添加一个表(甚至不需要)。这不是一种不常见的做法,并且使您的 bc 从拥有 ID 生成逻辑的责任中解脱出来(在某些情况下,这可能非常有用)。
注意:与我们软件世界中的所有事物一样,这需要权衡取舍:
我不得不说以上所有观点都很小众,我不认为这真的是一个问题。
有关此实践的参考和更多信息,您可以阅读 Twitter 的 Snowflake 项目。Snowflake 生成顺序的类似 guid 的 64 位整数 id,但很多(如果不是全部)原则仍然适用于这种情况。在很多讨论 Snowflake 的文章中有很多关于这种做法的信息和最佳实践。
问候, 萨瓦斯
我认为你可以有两种选择:
如果对象创建成本不高,则不必最终保持一致。在 DB 中创建对象并返回生成的 ID。
如果代价高昂,请将对象创建分解为小单元。根对象应该简单快速地创建,以便在数据库中持久化并返回生成的 ID。让通过事件/消息最终一致地创建其他子对象/聚合。