zoukankan      html  css  js  c++  java
  • 秒杀抢购时的超卖处理

    类似商城的秒杀场景,大家肯定都遇到过。如何处理好秒杀时候商品的库存限制问题,真的一直让人头大。

    常见的处理方案不外乎下面两种:

    1、锁

    表锁、行锁、文件锁。将需要操作的商品数据锁定,当前用户购买成功后,释放锁,允许其他用户操作该条数据。

    2、队列

    将请求放入队列中,也就是所有的请求都进行排队等待,按照顺序依次处理。并发请求都放到队列中,由额外进程串行处理,并发问题就不存在了,但是要额外进程支持以及处理延迟严重。

    以上两种方案都避免不了“等待”的问题,高并发极端场景下,很可能会造成系统响应异常。暂时不对这两种方案作详解。

    最近在学习 redis,发现可以结合 redis 的事物和 watch 命令巧妙解决超卖的问题。

    老规矩,使用 watch 之前先来了解下它的特性。毕竟使用场景是以事物的特性为基础的。

    watch 命令可以监控一个或多个键,一旦其中一个键被修改或删除,之后的事物就不会执行。监控一直持续到 exec 命令。

    话不多说,直接上代码。

    $redis = JRedis::getInstance();
    $key = 'saleCount:id:3';
    
    $redis->watch($key);
    //销量
    $sales = $redis->get($key);
    //库存
    $qty = 8;
    if ($sales >= $qty) {
        exit("已售罄");
    }
    //开启事务
    $redis->multi();
    $redis->incrby($key, 1);
    $result = $redis->exec();
    if ($result) {
        //执行数据库的销量增加操作,执行订单创建等操作
        exit("校验成功,开始数据库操作");
    } else {
        $redis->incrby($key, -1);
        exit("重新下单");
    }

    亲测效果杠杠的,而且就效率来说,要优于锁和队列。而且,还可以使用 redis 分摊数据库的压力,岂不是美滋滋。

    5分推荐。

    好文章分享:

    https://zhuanlan.zhihu.com/p/269746986

    https://zhuanlan.zhihu.com/p/336113193

  • 相关阅读:
    [原创]ExtAspNet秘密花园(二) — 一切从头开始
    使用领域定义建模语言来提高生产力
    报表控件团队成立了!!
    常见的程序语言分类的区别(简要说明)
    怎样做一名“专业”的程序员?
    推荐一个计数器网站
    在c中嵌入sql操作PostgreSQL
    让Visual C++ 2005 Express Edition也可以开发windows应用程序
    使用PowerDesigner进行代码生成
    sdmagazine与Dr. Dobb's Journal合并了?
  • 原文地址:https://www.cnblogs.com/suojian/p/14128964.html
Copyright © 2011-2022 走看看