redis decr 防止超卖_秒杀常见问题(超卖问题)

问题描述

秒杀系统优化以及解决超卖问题_dazou的博客-CSDN博客_秒杀超卖解决方案​blog.csdn.net
bc0d4055dc706037bf47ba9f5db9073b.png

在众多抢购活动中,在有限的商品数量的限制下如何保证抢购到商品的用户数不能大于商品数量,也就是不能出现超卖的问题;还有就是抢购时会出现大量用户的访问,如何提高用户体验效果也是一个问题,也就是要解决秒杀系统的性能问题。

解决超卖问题

每一个用户只能抢购一件商品的限制;在数据库减库存时加上库存数量判断,库存数量为0时阻止秒杀订单的生成。

  • 在数据库减库存时加上库存数量判断,防止数据变为负数
  • 数据库加唯一索引,防止用户重复购买

解决性能问题

  • 使用Redis缓存预减库存,减少数据库的访问。因为缓存的访问速度比数据库访问快得多。
  • 使用内存标记,减少Redis缓存的访问次数。
  • 使用队列等异步手段,请求先入队缓冲,异步下单,将数据写入数据库,增强用户体验。

性能解决方案

总体思路就是要减少对数据库的访问,尽可能将数据缓存到Redis缓存中,从缓存中获取数据。

  1. 在系统初始化时,将商品的库存数量加载到Redis缓存中
  2. 接收到秒杀请求时,在Redis中进行预减库存,当Redis中的库存不足时,直接返回秒杀失败,否则继续进行第3步;
  3. 将请求放入异步队列中,返回正在排队中;
  4. 服务端异步队列将请求出队,出队成功的请求可以生成秒杀订单,减少数据库库存,返回秒杀订单详情。
  5. 用户在客户端申请秒杀请求后,进行轮询,查看是否秒杀成功,秒杀成功则进入秒杀订单详情,否则秒杀失败。

缺陷

  • 由于是通过异步队列写入数据库中,可能存在数据不一致。

其他解决方案(超卖)

1.redis事务处理

我们可以使用redis中的监听(watch)方法,去监听库存数量,一旦库存数量在其他客户端发生改变,后续操作则会失败。

2. redis分布式锁
分布式锁确保只有一个线程会操作库存

  • 加锁(占个位置,后续的进不来):setnx命令: 只在键key不存在的情况下,将键key的值设置为value 。若键key已经存在, 则不做任何动作。
  • 解锁(用完了,就把位置让出来):del(key)
  • 锁超时(万一中间出现点意外,没有解锁,过几秒会自动释放)expire(key,30)

3.redis队列(rpoplpush的安全队列)

把每一件商品都lpush到redis队列中,利用lpop从队列中去取

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是指在高并发情况下,多个用户同时购买同一商品,导致库存减少过实际数量的情况。为了解决这个问题,可以使用Redis和MySQL的组合。 一种解决问题的方法是使用Redis作为缓存,将商品的库存数量存储在Redis中,并在用户购买时进行库存的检查和更新。具体步骤如下: 1. 在MySQL中创建一个商品表,包含商品的id、库存数量等字段。 2. 在Redis中创建一个键值对,键为商品的id,值为库存数量。 3. 当用户购买商品时,首先从Redis中获取商品的库存数量。 4. 如果库存数量大于0,则进行购买操作,并将库存数量减1。 5. 同时更新MySQL中的库存数量,确保数据的一致性。 6. 如果库存数量为0,则表示商品已售罄,无法购买。 以下是一个使用PHP和Redis解决问题的示例代码: ```php // 获取商品库存数量 $sql = "select id, num, money from ims_hotmallstore_goods where id=".$goods_id; // 执行SQL查询操作... // 从Redis中获取商品库存数量 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $stock_key = 'goods_stock:'.$goods_id; $stock = $redis->get($stock_key); // 判断库存数量是否大于0 if ($stock > 0) { // 进行购买操作 $sql = "update ims_hotmallstore_goods set num=num-1 where num>0 and id=".$goods_id; // 执行SQL更新操作... // 更新Redis中的库存数量 $redis->decr($stock_key); // 返回购买成功的信息 echo "购买成功!"; } else { // 返回库存不足的信息 echo "库存不足!"; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值