• 乐观锁与悲观锁


    1.为什么要有悲观锁、乐观锁?

    商品购买过程一般如下图所示:

    用户买东西的时候,数据库通常会先查一下库存,有足够的库存后用户可以继续购买,用户确认订单后就修改库存。

    假设有这么一个场合。一个秒杀活动放出了3台macbook,1元一台。

    用户甲手快买了2件。按照步骤来是,数据库查询有没有足够的库存,查了一下,有3个库存。然后数据库还没来得及修改库存的时候,用户乙也买了2台,数据库查询库存,也有3件。结果用户甲和用户乙都成功下单了。3件库存结果卖了4件出去。悲观锁和乐观锁就是为了解决这种问题而出现的。

     

    2.悲观锁

    悲观锁就是总是假设最坏的情况,即假设每次都会出现上面的那种情况。悲观锁的解决方案就是当数据库查询库存时,即让数据库对该记录加锁,直到修改完库存后再解锁。在记录被加锁之后,只有当记录被解锁后,其他用户才能进行库存查询。

    select stock from tb_sku where id=1 for update;    # sql原生语句用法
    
    SKU.objects.select_for_update().get(id=1)    # django ORM用法

    悲观锁类似于在多线程资源竞争时添加的互斥锁,容易出现死锁现象,采用不多。

    3.乐观锁

    乐观锁就是总是假设最好的情况,即假设每次都不会出现上面的那种情况。乐观锁其实并没有加锁,只是在更新数据时,判断数据在查询出来之后是否有被别人修改过,如果没有修改才更新,否则不更新(更新商品库存时,先判断库存是否与之前查询的一样,如果一样则更新,否则不更新)。

    update tb_sku set stock=1 where id=1 and stock=3;    # sql原生语句写法

    SKU.objects.filter(id=1, stock=3).update(stock=1) # django ORM写法

    注意:乐观锁并不存在真正的锁,只是在修改数据时作了数据是否有被修改的判断

    特别注意:如果使用乐观锁,记得要修改数据库的隔离级别为读已提交(Read Committed)

  • 相关阅读:
    容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?
    Spring Controller里注入Feign的Interface报红提示的问题
    几种常见的日志
    个人博客搭建方案选择
    elasticsearch常用操作命令
    kafka操作命令
    centos7.0安装java环境
    CentOS安装jdk的三种方法
    在OAuth2中 自定义tokenServices来提供个性化服务,每次刷新token并让原token在5分钟内有效
    解决HttpServletRequest的输入流只能读取一次的问题(转)
  • 原文地址:https://www.cnblogs.com/chichung/p/10055556.html
Copyright © 2020-2023  润新知