redis 实现防止超卖现象

1 篇文章 0 订阅

redis 实现防止商品超卖现象

redis实现防止商品超卖现象主要是利用redis的原子性,在判断是否超卖过程中,最好不要有数据库查询这种具有耗时性的操作。

话不多说直接上代码

$client = new Redis();
$client->connect("127.0.0.1",6379);

第一步:肯定是连接redis

$productTotal = 10; //产品总数
$productOverKey = "pd_test_key";

$client->setnx($productOverKey,0);
$productOver = $client->get($productOverKey);
$client->watch($productOverKey);

第二步:

  • 假设当前商品总数量productTotal 为10个
  • 设置已卖出产品数量的key为pd_test_key,并设置初始值为0
  • 然后利用watch监听这个key
  • 获取已卖出商品的数量
// 如果卖出的产品数量比总数小则可以执行操作
if($productOver < $productTotal) {
    $client->multi();
    $client->incr($productOverKey);
    if($client->exec()) {
        // 执行数据库操作,
        //产品已抢购成功

        $mysql = mysqli_connect("127.0.0.1","root","123456","test");

        mysqli_query($mysql,"INSERT INTO `pdtest` (`status`,`create_time`) VALUES ('ok','".Date("Y-m-d H:i:s")."')");

        mysqli_close($mysql);

    }else {
        // 抢购失败
    }

}else {
    // 没货了
}

第三步:

  • 判断卖出的数量是否已经超过总数量
  • 启用redis的事务,这是保证原子性的条件
  • 直接在事务中增加已卖出数量,(watch会监听,如果其他地方对这个key进行了更改,则事务会执行失败)
  • 等事务执行成功以后就可以对数据库进行操作了

博主这里是利用redis的watch和multi的原子性,当然也可以利用lua脚本来实现原子性

用ab测试工具测试

ab -c 100 -n 1000 http://test.net

没有出现超卖现象

ps:

  • 缺点之一:要对商品的总数量和卖出数量的key进行维护
  • 分布式的话也可以使用zookeeper来实现分布式锁
  • 如果流量十分大的话,可以配和nginx等进行限流,超过指定数量以后的请求直接显示另外一个网页
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值