使用Redis锁概念实现秒杀

栏目: 数据库 · Redis · 后端 · 发布时间: 8年前

内容简介:秒杀功能一般在购物网站比较常见,通过设定1到2件特别低价的商品,调动用户的积极性。具体是实现的思路: 1.用户发送秒杀请求,后台程序检测秒杀产品是否已经售完; 2.如果秒杀的产品库存数量大于0,则该请求秒杀成功,减少库存数量,更新用户的信息;

秒杀功能一般在购物网站比较常见,通过设定1到2件特别低价的商品,调动用户的积极性。

具体是实现的思路:

1.用户发送秒杀请求,后台程序检测秒杀产品是否已经售完; 2.如果秒杀的产品库存数量大于0,则该请求秒杀成功,减少库存数量,更新用户的信息;

表面上看没有问题,如果放到现实情况下,则暴露出严重的BUG:

从商品库存数量检测到秒杀成功后,更新库存剩余数量(商品数量减1),这之间只有一步,但是在大并发量情况下,几十个(甚至几百个)用户同时查询、减少,会造成库存数量为负数的情况,即多个用户同时秒杀到一款产品。

这就需要用到 redis 锁的机制,来限制并发查询和更新。

demo示例:

<?php
/**
  *
  * 秒杀请求程序入口
  *
  */
$redis = new Redis();
$ret = $redis->connect("127.0.0.1", 6379);
if ($ret === TRUE) {
    // 检测秒杀是否结束
    if ($redis->get('goods.num') <= 0) {
            echo ("秒杀已经结束");
            return False;
    }
    // 获取锁之后才可以处理库存
    tryagain:
    $lock = $redis->setnx("lock", 1);
    if ($lock === FALSE) {
            goto tryagain;
    }
    // 获取锁之后检测库存
    if ($redis->get('goods.num') <= 0) {
            echo ("秒杀已经结束");
            //删除锁
            $redis->delete("lock");
            return False;
    }
    // 更新秒杀产品剩余库存
    $last_num = $redis->decr('goods.num');
    if ($last_num < 0) {
            echo ("秒杀已结束");
            // 删除锁
            $redis->delete("lock");
            return False;
    } else {
            // 更新用户账户 记录秒杀成功用户信息
            echo ("秒杀成功");
            // 删除锁
            $redis->delete("lock");
            return True;
    }
} else {
    // 连接异常
    die("Redis连接失败");
}

这里唯一要注意的一点,没有处理死锁的情况,即完成商品数量更新后,删除锁失败。


以上所述就是小编给大家介绍的《使用Redis锁概念实现秒杀》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

从0到1

从0到1

彼得·蒂尔、布莱克·马斯特斯 / 高玉芳 / 中信出版股份有限公司 / 2015-1-1 / CNY 45.00

图书简介: http://v.youku.com/v_show/id_XOTA0NjcyMzE2.html?wm=3333_2001 硅谷创投教父、PayPal创始人作品,斯坦福大学改变未来的一堂课,为世界创造价值的商业哲学。 在科技剧烈改变世界的今天,想要成功,你必须在一切发生之前研究结局。 你必须找到创新的独特方式,让未来不仅仅与众不同,而且更加美好。 从0到1,......一起来看看 《从0到1》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具