千家信息网

redis中怎么防止抢购商品超卖

发表于:2024-12-03 作者:千家信息网编辑
千家信息网最后更新 2024年12月03日,本篇文章为大家展示了redis中怎么防止抢购商品超卖,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。使用redis的list进行测试思路是设置一个redis列表
千家信息网最后更新 2024年12月03日redis中怎么防止抢购商品超卖

本篇文章为大家展示了redis中怎么防止抢购商品超卖,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

  • 使用redis的list进行测试

    思路是设置一个redis列表List,假设有十个商品,每次请求先判断List的长度,小于十就能抢到商品,将用户信息存放到List中。代码如下

 //进行抢购    protected function way_list(){$num = $this->redis->lLen();if($this->redis->lLen()>=self::AMOUNTLIMIT){$this->writeLog("抢购失败".$num);return;}else{$this->redis->rPush($num);$this->writeLog("抢购成功".$num);}}

结果:失败!

可以很明显数量不对顺序也不对。

分析了下原因,在代码执行时,多用户并发请求时,第一个用户判断List长度符合条件还未进行List写入时,第二个用户也通过了List长度判断。所以就导致执行失败。

这就没有利用到redis的原子性

所以进行了改良

  • 使用redis 的incrby。incrby将制定key 的值增加指定的增量,并返回增量后的值。是一个原子性操作。所谓的原子性操作就是执行该方法后要嘛成功要嘛失败。

思路就是设置一个键值对存放被抢购数量,每次一个用户进来就将该值加一进行判断,如果小于抢购的商品数量则抢购成功,否则失败。代码如下

 protected function way_string(){//判断是否有初始化        if(!$this->redis->exists(self::sold_name)){$this->redis->setnx(self::sold_name,0);}if($this->redis->incrby(self::sold_name,1) > self::AMOUNTLIMIT){$this->writeLog('失败');}else{$this->writeLog('成功');}}

结果

压力测试了几次都没有出现问题

通过apache自带的ab压力测试,进行五百次连接请求,并发三百次,没有出现超卖行为。

总结:会出现超卖主要是由于用户在请求的时候,代码在执行是有先后,会导致执行结果不符合预期。而采用redis的原子性就能避免。

上述内容就是redis中怎么防止抢购商品超卖,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

0