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,所以才需要在程序里判定唯一性,然后抛出友好的异常信息。

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

 

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

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

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

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

备注

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值