秒杀,怎么防止库存超卖

所谓秒杀,就是网络卖家发布一些超低价格的商品,所有买家在同一时间网上抢购的一种销售方式。由于商品价格低廉,往往一上架就被抢购一空,有时只用一秒钟。

先来就库存超卖的问题作描述:一般电子商务网站都会遇到如团购、秒杀、特价之类的活动,而这样的活动有一个共同的特点就是访问量激增、上千甚至上万人抢购一个商品。然而,作为活动商品,库存肯定是很有限的,如何控制库存不让出现超买,以防止造成不必要的损失是众多电子商务网站程序员头疼的问题,这同时也是最基本的问题。

在秒杀系统设计中,超卖是一个经典、常见的问题,任何商品都会有数量上限,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的难点。

解决方案

  • 悲观锁

通过悲观锁解决超卖

  • 乐观锁

通过乐观锁解决超卖

  • 分段执行的排队方案

通过分段执行的排队方案解决超卖

1.mysql锁机制,悲观锁InnoDB行级锁方案,不建议使用,对数据库压力较大,如果出现死锁会导致一直不能更新,除非kill掉进程

2.mysql乐观锁 不使用第三方情况下可以使用此方案

3.redis incrby decrby原子性操作,防止超卖

4.为方便扩展,把库存类抽象出接口,方便以后扩展,也可以使用其它方式实现

1.1.mysql锁机制,悲观锁,InnoDB行级锁方案,查询需使用索引

1.事务级别必须为 SERIALIZABLE 级别

2.查询条件验证库存是否够本次购买,例: id = 1 AND inventory >=1

3.PDO update更新后,不但要验证返回状态是否为!==false,并且同时验证影响行数是否大于0

4.数据库链接一定要使用同一链接,单例或DB链接传入,建议使用单例,由于测试网上找了个db类,没有实现单例,所以使用比较笨的方法,传递数据库链接

5.update件件增加验证购买数量条件 AND inventory >=1

1.2.mysql乐观锁

数据库表增加版本字段如version,每次修改时版本号+1

如果更新操作顺序执行,则数据的版本(version)依次递增,不会产生冲突。但是如果发生有不同的业务操作对同一版本的数据进行修改,那么,先提交的操作(图中B)会把数据version更新为2,当A在B之后提交更新时发现数据的version已经被修改了,那么A的更新操作会失败。

PDO update更新后,不但要验证返回状态是否为true,并且同时验证影响行数是否大于0

1.3.redis原子性操作

incr/decr原子性操作,incr增加,decr减少

//此处不可以取出后放入php变量判断库存,否则会出现幻读,导致超卖

if ($redis_client->decrby($key, $parmas['num']) > -1) {

//减库存

$goods = new Goods();

$parmas['version'] = 1;

return $goods->subInventory($parmas);

} else {

//购买多个时,如库存不足,需要把数量加回去,否则会出现库减库存,商品并没有卖出去

$redis_client->incrby($key, $parmas['num']);

return false;

}

使用redis测试时,每次修改完库存需要删除KEY:DEL goods_1

2.测试

配置使用方式

//db 悲观锁(事务级别SERIALIZABLE) db2 mysql乐观锁 redis redis方式

define('INVENTORY_TYPE', 'db2');

并发小时可能不会有问题,如查并发较大会有超卖现像,为了可以重现超卖下面代码加入2秒迟时

services/inventory/db/Inventory.php 31行左右

$data = $goods->getInventory($params);

sleep(2); //停2秒,方便测试出问题

nginx配置站点mall.com

本机hosts绑定域名 10.211.55.100 mall.com(10.211.55.100为实际站点的ip)

测试方法使用ab测试,请求100,并发10

ab -n100 -c10 http://mall.com

3.问题

注意

由于订单流程中,把验证库存和扣减库存放在了下订单前,可以减少下订单数量和开启的事务数,但如果用户在扣减库存后下订单过程中失败,会出现少卖现象

如果对库存要求不高,可以不用考虑,如果对库存要求较高,需要把扣减成功下单失败对应的订单保存到日志中,然后异步处理恢复库存或用户补给

php 有关秒杀防止超卖面试题相关推荐

  1. Redis解决商品秒杀与超卖

    这个是实体店我们会看到的场景,100件商品,1人1件,最后200人中只有100人能买到商品,剩下100人只能空手而归.如果您开了家网店,同样你开起了秒杀的活动,可能同时会有1000人通过不同的终端访问 ...

  2. PHP:关于PHP商城秒杀防止超卖问题

    关于PHP商城秒杀防止超卖问题 序言: 在同样对数据操作的代码下,redis事务比lua脚本还要慢上许多,会偶尔出现1-10单超卖的现象. 如果想要使用redis事务,删减库存的情况,用redis-& ...

  3. Spring Boot + redis解决商品秒杀库存超卖,看这篇文章就够了

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:涛哥谈篮球 来源:toutiao.com/i68366119 ...

  4. redis如何解决秒杀超卖java_Spring Boot + redis解决商品秒杀库存超卖,看这篇文章就够了...

    作者:涛哥谈篮球 来源:toutiao.com/i6836611989607809548 问题描述 在众多抢购活动中,在有限的商品数量的限制下如何保证抢购到商品的用户数不能大于商品数量,也就是不能出现 ...

  5. 【Redis】实战篇:优惠卷秒杀 (库存超卖问题、一人一单问题)

    文章目录 3.1 全局唯一ID 3.2 -Redis实现全局唯一Id 3.3 添加优惠卷 3.4 实现秒杀下单 3.5 库存超卖问题分析 3.6 乐观锁解决超卖问题 3.7 优惠券秒杀-一人一单 3. ...

  6. Redis实战——优惠券秒杀(超卖问题)

    1 实现优惠券秒杀功能 下单时需要判断两点:1.秒杀是否开始或者结束2.库存是否充足 所以,我们的业务逻辑如下 1. 通过优惠券id获取优惠券信息 2.判断秒杀是否开始,如果未返回错误信息 3.判断秒 ...

  7. 秒杀商品超卖了,差点被辞退...

    「 关注"石杉的架构笔记",大厂架构经验倾囊相授 」  儒猿技术团队最新出品 <基于ShardingSphere的分库分表实战> 文章来源:[公众号:微观技术] 随着中 ...

  8. 解决秒杀系统超卖问题的三种方案

    在秒杀系统设计中,超卖是一个经典.常见的问题,任何商品都会有数量上限,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的难点. 一.问题描述 在多个用户同时发起对同一个商 ...

  9. 秒杀商品超卖事故:Redis分布式锁请慎用!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:浪漫先生 来源:juejin.im/post/6854573 ...

最新文章

  1. mysql dump xtrabackup_MySQL--备份恢复【Mysqdump+xtrabackup(XBK)】
  2. Android中BroadcastReceiver组件详解
  3. 【Python基础】Python正则表达式入门到入魔
  4. VTK:PolyData之KochanekSplineDemo
  5. KVM虚拟化的简单概论
  6. java md5 密钥_Java 生成16/32位 MD5密钥串
  7. 漫步最优化三十九——Fletcher-Reeves法
  8. [视频教程]用Unity3d开发跳一跳小游戏
  9. 有道精品课数据中台建设实践
  10. leetcode力扣78. 子集
  11. uiautomatorviewer报错“Error taking device screenshot: EOF” ,
  12. 页面缓存 OutputCache
  13. 良好的XHTML编写习惯
  14. JDK获取所有的系统参数
  15. html 数据库 留言板,使用html5本地数据库留言本代码分享
  16. 设计不难学,这10款软件总有一款适合你
  17. 喇叭天线的增益计算matlab源代码,一种测量标准喇叭天线增益的方法与流程
  18. 算法产品化---人脸识别采集终端的摄像头品质要求
  19. Linux驱动开发(九)---树莓派I2C设备驱动开发(BME280)
  20. xshell卸载注册表删除问题

热门文章

  1. xxl-job优雅停止执行器即客户端tomcat
  2. 遨博协作机器人ROS开发 - 机械臂自主避障
  3. 智合同——关于合同要素智能提取和合同智能审查的功能说明
  4. 新手小白如何快速学好PS平面设计?需要什么技巧?
  5. 光影如何制作?怎么才能学好PS?磨金石教育来帮你。
  6. [USACO06FEB]数字三角形Backward Digit Su…
  7. 九宫怎么排列和使用_广告视频配音剪映零基础入门教程第二十三篇:剪辑之九宫格教程...
  8. wav文件的采样位数从16位转换到8位的C语言实现
  9. php 按键连击,写了一个独立按键 支持组合键、单键长按,连发功能的例子
  10. LeTex 常用操作