• 【Redis实现秒杀业务②】超卖问题的解决方案


    我们在上一篇的文章中,实现了秒杀的基本业务,但是在并发的场景下,我们会发现代码存在诸多问题,超卖就是经典的问题之一。让我们来一起研究一下这玩意。

    什么是超卖

    超卖现象是秒杀业务中常见的现象,意指用户在购买指定商品的过程中,售卖的商品超过了商户的预期。

    超卖是怎么产生的

    如果只剩最后一件商品的时候,恰好这时有两个线程同时进入这个红色框框,就会一起进入更新的代码,于是就会产生超卖现象了。

    在这里插入图片描述

    图解超卖

    正常情况

    在这里插入图片描述
    超卖情况
    在这里插入图片描述

    解决方案

    超卖问题是典型的多线程安全问题,针对这一问题的常见解决方案就是加锁:

    • 悲观锁
    • 乐观锁

    悲观锁

    认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行。
    例如Synchronized、Lock都属于悲观锁。

    悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。

    但是在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会,同时也会降低并发性能。

    悲观锁的实现----MySQL版
    要使用悲观锁,我们必须关闭mysql数据库的自动提交属性。MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。我们可以使用命令设置MySQL为非autocommit模式:set autocommit=0;

    //开始事务
    begin; 
    //查询出商品库存信息,使用 for update 加上排它锁
    select quantity from items where id=1 for update;
    //修改商品库存
    update items set quantity=100 where id = 1;
    //提交事务
    commit;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    乐观锁

    认为线程安全问题不一定会发生,因此不加锁,只是在更新数据时去判断有没有其它线程对数据做了修改。

    如果没有修改则认为是安全的,自己才更新数据。

    如果已经被其它线程修改说明发生了安全问题,此时可以重试或异常。

    相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。

    乐观锁不会产生任何锁和死锁,拥有更好的性能。

    乐观锁的实现
    通过一个单独的可以顺序递增的version字段,可以避免ABA问题:

    //查询出商品信息,version = 1
    select version from items where id=1
    //修改商品库存为2
    update items set quantity=2,version = 3 where id=1 and version = 2;
    
    • 1
    • 2
    • 3
    • 4

    除了version以外,还可以使用时间戳,因为时间戳天然具有顺序递增性。

    减小乐观锁力度,可以最大程度的提升吞吐率,提高并发能力:

    //修改商品库存
    update item 
    set quantity=quantity - 1 
    where id = 1 and quantity - 1 > 0
    
    • 1
    • 2
    • 3
    • 4

    选择悲观锁还是乐观锁

    • 乐观锁并未真正加锁,效率高。然而,如果锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。
    • 悲观锁依赖数据库锁,效率低。更新失败的概率比较低。
    • 在高并发的业务场景下,悲观锁越来越少被使用了。

    我们下一章就来具体实现一下乐观锁的方案。

  • 相关阅读:
    MySQL——排序查询
    开发者必读:2022年移动应用运营增长洞察白皮书
    hbuilderx ios自定义基座真机测试
    文件上传漏洞-upload靶场5-12关
    【Java面试】TCP协议为什么要设计三次握手?
    java反序列化-CC1
    【JavaSE】数据类型与变量
    动静态库(生成和使用)
    简单的图片二维码制作教程,你感兴趣吗?
    Python用RNN神经网络LSTM优化EMD经验模态分解交易策略的股票价格MACD分析
  • 原文地址:https://blog.csdn.net/CSDN_SAVIOR/article/details/125274005