使用Redis锁概念实现秒杀

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

内容简介:秒杀功能一般在购物网站比较常见,通过设定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锁概念实现秒杀》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

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

这才是马云

这才是马云

陈伟 / 浙江人民出版社 / 2011-5 / 30.00元

“幽默马云”、“开心马云”、“顽皮马云”、“狂妄马云”等。《这才是马云》从各个角度揭开了千面马云的真面目,告诉你一个与想象中大不一样的马云。这不只是一本书,更像一部喜剧电影,让你通过声音、色彩、表情等诸多要素走近马云,感受阿里巴巴。没有冗长的说教,只有让人忍俊不禁的细节;没有高深的理论,只有通俗、诚恳的陈述。作者借幽默平常的琐事,记录下马云“可爱”的一面,看完后让人恍然大悟:原来,马云是这样一个人......一起来看看 《这才是马云》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试