• .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操作使用第一个线程读取的版本号,否则会使用第二次读取的版本号。

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

    备注

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

    转载自http://www.cnblogs.com/happyframework/archive/2013/05/29/3105310.html

  • 相关阅读:
    《游戏改变世界》笔记
    2017第6周日
    换个角度看执行力
    怎样拥有执行力和高效能
    提高个人执行力的五个关键
    Apache服务器部署多个进程
    IE的Cookie目录和临时缓存目录的关系
    IE/Firefox/Chrome等浏览器保存Cookie的位置
    在浏览器中简单输入一个网址,解密其后发生的一切(http请求的详细过程)
    如何设置win7系统的文件夹为系统文件,从而隐藏文件夹
  • 原文地址:https://www.cnblogs.com/ShaYeBlog/p/3107756.html
Copyright © 2020-2023  润新知