zoukankan      html  css  js  c++  java
  • DDD:如何处理“唯一性”业务逻辑

    背景

    唯一性约束是一个经常出现的业务逻辑,刚开始我觉得非常简单,不过深入考虑后,发现实现起来还不是那么简单,下面就让我们分析一下。

    两种场景下的唯一性约束

    第一种场景:聚合根的某个属性的唯一性约束

    示例:用户的用户名必须唯一。

    第一种实现思路:后验证+不用数据库索引,在插入用户名和修改用户名之后执行一次验证,这个验证逻辑执行的事务隔离级别必须处于“读未提交”级别。

     1 public volid Insert(User user)
     2 {
     3     using(var ts1 = new TransactionScope("读已提交"))
     4     {
     5         DoInsert(user);
     6         using(var ts2 = new TransactionScope("读未提交"))
     7         {
     8             //如果违背约束,抛出异常。
     9         }
    10         ts1.Complete();
    11     }
    12 }

     第二种实现思路:前验证+不用数据库索引,在插入用户名和修改用户名之前执行一次验证,整个事务运行在“串行化”隔离级别。

    1 public volid Insert(User user)
    2 {
    3     using(var ts = new TransactionScope("串行化"))
    4     {            
    5         //如果违背约束,抛出异常。
    6         DoInsert(user);
    7         ts.Complete();
    8     }
    9 }

     第三种实现思路:前验证+数据库索引,在插入用户名和修改用户名之前执行一次验证,整个事务运行在“读已提交”隔离级别。

    1 public volid Insert(User user)
    2  {
    3      using(var ts = new TransactionScope("读已提交"))
    4      {            
    5          //如果违背约束,抛出异常。
    6          DoInsert(user);
    7          ts.Complete();
    8      }
    9  }

     第四实现思路种:内存锁。

    有朋友会想,为啥不直接用数据库索引呢?失败了就跑出异常,因为我们需要收集到友好的异常信息显示给UI,所以才需要在程序里判定唯一性,然后抛出友好的异常信息。

    总体来说我觉得第三种思路在现实中比较方便。

    第二种场景:聚合内某个实体的属性的唯一性约束

    示例:订单的订单项的产品必须唯一。

    第一种实现思路:聚合根的乐观锁+聚合自身必须保证这种约束。

    我觉得这个场景下只有这一种实现是比较合理的,就不介绍其他思路了。

    备注

    在健身房仓促写就,大家多提意见。

  • 相关阅读:
    VMware安装windows xp系统
    Linux socket编程中调用 inet_ntoa 函数产生的段错误 “Segmentation fault (core dumped)” 的原因及解决办法
    动态规划
    Hadoop中的setOutputKeyClass和setOutputValueClass
    C++ priority_queue的自定义比较方式
    BFPRT 算法(TOP-K 问题)
    map和unordered_map的区别
    关节点 与 重(双)连通图
    fd=open("./file1",O|CREAT,0666)中的0666是什么意思,它和chmod中的权限有什么区别?
    普通用户要用IPC_CREATE|0666才能运行代码
  • 原文地址:https://www.cnblogs.com/happyframework/p/3137991.html
Copyright © 2011-2022 走看看