zoukankan      html  css  js  c++  java
  • 乐观锁+版本号解决锁竞争问题

    乐观锁+版本号解决锁竞争问题

    在高并发的场景下,经常会遇到这种情况:
    A请求过来,查询出来一条数据,进行update操作,与此同时B请求也在这个时候过来,对这条数据进行查询,并进行操作。此时就会出现B在A之后进行查询操作,但是实际B的数据却被A覆盖。

    这种情况并不少见,有时候会为了避免这种情况,我们会引入锁来解决这种问题,常见的比如使用ReetrantLock或者synchronized同步块等悲观锁的方式来实现,其实在这里,我们也可以尝试使用乐观锁+版本号的方式来进行处理。

    可以举个更具体的案例来说明一下。
    A请求

    select num from store where id='1';

    此时获取到num=99

    这时候B请求进来后,也发起查询

    select num from store where id='1';

    此时由于A请求尚未进行update,B请求获取到的num也等于99。
    这时候A进行update操作

    update store set num =${num} +1 where id='1';

    这时候写入数据库的num即为100
    此时B请求也发起了更新操作:

    update store set num =${num} +1 where id='1';

    这时候我们的预期本应该是101的,但是实际上B又在数据库写入了100.

    解决方案:
    这时候我们可以引入一个版本号的概念,来巧妙的解决这个问题。

    A请求

    select num,version from store where id='1';

    此时假设num=99,version=1,这时候B依然发起select请求:

    select num,version from store where id='1';

    没有意外,B取到的version也是1,这时候A进行update写入,此时:

    update store set num =${num} +1,version=${version}+1 where id='1' and version='1'

    由于A进行行级锁,此时version也变成了2。
    B这时候发起操作,由于select的时候,版本号依然为1,此时实际B无法进行update的

    update store set num =${num} +1,version=${version}+1 where id='1' and version='1'

    我们可以看到由于在数据库的版本号已经变成2,了,实际version=1会让B请求的更新数据不能成功。

  • 相关阅读:
    OWIN系列之自己动手编写中间件
    Visual Studio2015使用tinyfox2.x作为Owin Host调试教程
    CentOS7下自定义目录安装mono+jexus教程
    TinyFox/Jexus如何正确使用配置文件
    CentOS7下默认目录安装mono+jexus教程
    CentOS 7 常用命令
    javascript动态创建script,并监听onload、onerror
    javascript if
    StackExchange.Redis常用API
    EF EntityState的几种状态
  • 原文地址:https://www.cnblogs.com/lqmblog/p/13745213.html
Copyright © 2011-2022 走看看