.NET:防止并发修改 之 离线乐观锁代码示例(菜鸟必读)

背景

小明和小强同时签出了源代码,如果小强先提交,那么提交成功是合理的,接着小明提交了修改,这时源代码服务器就会告诉小明有人在他读取之后做了修改,问他如何处理,源代码服务器会让小明把修改合并后再提交。这就是乐观锁策略,当然源代码服务也可以配置为悲观锁以避免并行修改。

合理的规避并发修改是企业应用中不能回避的问题,但现实场景是,很多团队都回避这个问题。今天我介绍一下如何使用离线乐观锁处理并发修改。

相关文章:再谈在线悲观锁、离线悲观锁、在线乐观锁和离线乐观锁

思路

CAS:Compare And Swap,只有当要修改的值在我读取后没有被修改,才会被交换(修改)。

CAS是多线程领域的术语,比如:无锁的环形队列就是基于这个实现的。因为CAS的思想和乐观锁的思想一致,我就借用一下。

看一下离线乐观锁的应用场景:

上图包含了如下信息:

一、读取线程A1和修改线程A2是不同的线程,因此才叫离线。例如:表单的读取数据和修改。

二:CAS的Compare比较的是版本号,Swap的是整条记录。例如:EntityFramework允许你指定哪些属性是版本属性。

代码示例

设置版本字段

CAS

 1         /// <summary>
 2         /// 执行修改。
 3         /// </summary>
 4         public void Handle(TCommand command)
 5         {
 6             var unitOfWork = ServiceLocator.Current.GetInstance<TUnitOfWork>();
 7 
 8             unitOfWork
 9                 .GetRepository<TRepository>()
10                 .MarkAsModified(command.Aggregate);
11 
12             unitOfWork.Commit();
13         }

运行效果

注意事项

一、示例中我直接将读取线程读取的数据,离线修改后传递个修改线程了,这样两个线程只有一次读取逻辑,这保证了CAS中Compare的正确性。有些场景你可能需要在修改线程中也进行一次读取,然后将UI层修改的数据合并过来,这种情况就要注意了,必须要手工指定Compare操作使用第一个线程读取的版本号,否则会使用第二次读取的版本号。

二、乐观离线锁只适合重来成本很低的场景,否则用户编辑了两个小时,你告诉他出现并发问题了,他会疯的。这种成本很高的操作适合“离线悲观锁”。

备注

我就是一个行动跟不上思维的人,因为懒惰,我没有全面的在项目中采用乐观锁,下一个项目一定全面实施。

 

转载于:https://www.cnblogs.com/happyframework/archive/2013/05/29/3105310.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值