Domain driven design DDD-乐观并发属性(etag或时间戳)是否应该成为域的一部分?

Domain driven design DDD-乐观并发属性(etag或时间戳)是否应该成为域的一部分?,domain-driven-design,Domain Driven Design,从理论上讲,如果我们在聚合根级别实现乐观并发(在AR中更改实体在AR上更改版本),并假设我们使用版本属性的时间戳(只是为了简单起见)——时间线应该是AR上的一个属性,还是应该是读取模型的一部分(例如,更新)作为应用程序服务的单独参数,如: [伪] public class AppService{ . . . public void UpdateSomething(UpdateModelDTO model, int timestamp) { repository.GetMo

从理论上讲,如果我们在聚合根级别实现乐观并发(在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的问题,我希望通常的情况是:

  • 读取时,将读取版本标识符并将其发送到客户端
  • 更新时,客户机发回标识符,如果版本标识符不相同,存储库将返回某种错误

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

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

    聚合不应该关心任何其他问题,而应该关心与业务相关的关注点。它应该是纯的,没有任何基础设施问题

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

    另外,使用时间戳进行乐观锁定是很奇怪的;您最好使用一个整数,该整数在每次聚合发生变异时递增,并且在执行
    保存时预期会有(加载版本+1)

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

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


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

    不,我没有使用它。实际上,我在做任何选择之前都会问,因为我只是想知道ddd的正确做法。看看这个,我不确定我是否理解你的问题。您是在问聚合是否应该知道/关心ts/version属性/列/属性吗?是的,这就是我要问的。并发数据访问在某种程度上与DDD正交,因此:根据书本上的解决方案,答案是否定的。您能否更具体地说明您对应用程序级乐观并发的期望?你想让它解决什么问题?@guillaume31谢谢你的提问!我已经更新了我最初的帖子。时间戳只是为了简单起见,当然对OC来说是个糟糕的选择。好的,我明白你的意思。我有稍微不同的设置,db端生成版本,但重要的是AR与之无关。非常感谢!但如何处理同时更改的相同聚合?当您试图将聚合保存到基础架构层时,如何知道它是哪个版本?谢谢您的回答!我必须说,从性能/复杂性的角度来看,这听起来最符合逻辑,但我也听到一些ddd纯粹主义者说“绝对不”。这就是为什么我想知道是否有明确的答案“实际上为什么没有”。我想我会选择AR中的版本字段。DDD与数据访问技术的历史充满了妥协;-)做一个纯粹主义者是要付出代价的。正如我所说的,您可以尝试让您的域模型不受这些并发性问题的影响,但它可能会在性能、清晰度、复杂性等方面花费您的时间,这对我来说非常有意义。再次感谢你的想法!