【问题标题】:DDD - Should optimistic concurrency property (etag or timestamp) ever be a part of domain?DDD - 乐观并发属性(etag 或时间戳)是否应该成为域的一部分?
【发布时间】:2018-03-21 16:55:11
【问题描述】:

从理论上讲,如果我们在聚合根级别实现乐观并发(AR 中的更改实体会更改 AR 上的版本)并假设我们使用时间戳作为版本属性(只是为了简单起见) - 时间线应该是 AR 上的属性还是应该它一方面是读取模型的一部分,另一方面(例如更新)是应用程序服务的单独参数,例如:

[伪]

public class AppService{
.
.
.
   public void UpdateSomething(UpdateModelDTO model, int timestamp)
   {
      repository.GetModel(model.Identifier);
      model.UpdateSomething(model.something);
      repository.ConcurrencySafeModelUpdate(model, timestamp);
   }
}

我看到了两者的优点/缺点,但想知道哪个是按部就班的解决方案?

[更新]

为了回答@guillaume31 的问题,我期待通常的情况:

  1. 读取时,版本标识符被读取并发送到客户端
  2. 更新时,客户端发回标识符,如果版本标识符不同,存储库会返回某种错误。

我不知道它是否重要,但我想将创建/更新版本标识符的责任留给我的数据库系统。

【问题讨论】:

  • 我不确定我是否理解您的问题。你是在问聚合是否应该知道/关心那个 ts/version 属性/列/属性?
  • 是的,这就是我要问的。
  • 并发数据访问在某种程度上与 DDD 正交,所以:没有按书本的解决方案。您能否更具体地说明您对应用程序级乐观并发的期望?你希望它解决什么问题?
  • @guillaume31 感谢您的提问!我已经更新了我最初的帖子。

标签: domain-driven-design


【解决方案1】:

我假设,否则你不会问这个问题,你正在使用你的域模型作为数据模型(即 Hibernate 实体),那么你已经在你的域模型中引入了基础设施问题,所以我建议你继续并将时间戳添加到 AR。

【讨论】:

【解决方案2】:

除了与业务相关的问题外,聚合不应关心其他任何事情。它应该是纯粹的,没有任何基础设施问题。

数据库/持久性中的version 列是基础架构问题,因此不应反映在域层的聚合类中。

附:使用时间戳进行乐观锁定很奇怪;您最好使用一个整数,该整数在每次聚合发生变异时递增,并且在执行 save 时预期具有 (loaded-version + 1)。

public void UpdateSomething(UpdateModelDTO model)
{
     (model, version) = repository.GetModel(model.Identifier);
     model.UpdateSomething(something);
     repository.ConcurrencySafeModelUpdate(model, version + 1);
}

【讨论】:

  • timestamp 只是为了简单起见,对于 OC 来说当然是不好的选择。好的,我明白你的意思了。我的设置略有不同,其中 db 端生成版本,但重要的是 AR 与它无关。非常感谢!
  • 但是您如何处理同时更改的同一个聚合?当您尝试将其保存在基础架构层中时,如何知道哪个版本是聚合的?
  • @JohnnyWiller 您在重新水合聚合时加载版本,然后增加版本;如果另一个实例之前已经持久化,那么版本 + 1 已经在数据库中,并且唯一的 aggregate_Id+version 会抛出错误
  • 但在您的回答中,您提到聚合不应包含版本字段。不放进去怎么知道是哪个版本补水的?
  • @JohnnyWiller The Aggregate 不应该知道这些非商业的事情。您可以将加载的版本存储在存储库中,next 到加载的聚合实例
【解决方案3】:

没有按部就班的解决方案。有时您的聚合中已经有一个非常适合该角色的字段(例如LastUpdatedOn),有时您可以将其设为非域数据。出于性能原因,选择该字段作为获取聚合的同一查询的一部分可能是个好主意。

一些 ORM 提供了检测并发冲突的工具。一些 DBMS 可以为您自动创建和更新版本列。您可能应该在您的特定堆栈中寻找有关乐观并发的指南。

【讨论】:

  • 感谢您的回答!我必须说,从性能/复杂性的角度来看,这对我来说听起来最合乎逻辑,但我也听到一些 ddd 纯粹主义者说“严格不”。这就是为什么我想知道是否有一些明确的答案'为什么不,实际上'。我想我会在 AR 中使用版本字段。
  • DDD 与数据访问技术的历史充满了妥协 ;-) 成为纯粹主义者是有代价的。就像我说的那样,您可以尝试让您的域模型不受这些并发问题的影响,但这可能会在性能、清晰度、复杂性等方面付出代价。
  • 这对我来说很有意义。再次感谢您的想法!
猜你喜欢
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 2016-02-27
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2014-07-26
  • 1970-01-01
相关资源
最近更新 更多