秒杀核心设计(减库存部分)-防超卖与高并发
来源:互联网 发布:淘宝怎样增加销量 编辑:程序博客网 时间:2024/06/10 11:22
商品详情页面的静态化,varnish加速,秒杀商品库独立部署服务器这种就略过不讲了。只讨论库存部分的优化
mysql配置层面的优化可以参考我的这篇文章 《关于mysql innodb引擎性能优化的一点心得》
重点设计在数据库层面。
2张表:
第一张:判重表(buy_record),该用户有没秒杀过该商品
字段: id, uid, goods_id, addtime
第二张表:商品表 goods
字段: goods_id goods_num
方案1:
start transaction;
select id from buy_record where uid=$uid and goods_id=$goods_id;
if(结果不为空)
抛异常,回滚。
insert into buy_record。。。
if(受影响行数<=0)
抛异常,回滚。。。
select goods_num from goods where goods_id=$good_id;
if(库存<=0)
抛异常,回滚。。。
update goods set goods_num=goods_num-1 where goods_id=$goods_id;
if(受影响行数<=0)
该方法在高并发下几乎必然导致超卖。当库存为1的时候刚好多个用户同时 select goods_num from goods where goods_id=$good_id;此时库存刚好大于0,做update操作的时候必然减到小于0. 同时上面进行是否秒杀过的判重同样会出现类似问题
方案二:
start transaction;
select id from buy_record where uid=$uid and goods_id=$goods_id for update ;
if(结果不为空)
抛异常,回滚。
insert into buy_record。。。
if(受影响行数<=0)
抛异常,回滚。。。
select goods_num from goods where goods_id=$good_id for update ;
if(库存<=0)
抛异常,回滚。。。
update goods set goods_num=goods_num-1 where goods_id=$goods_id ;
if(受影响行数<=0)
抛异常,回滚。。。
该方法有效的防止了超卖,但是在每次select的时候加上了排它锁,每次select操作都会被堵塞 ,并发性能大大降低。
方案三: 对(uid,goods_id)加唯一索引!!
start transaction;
insert into buy_record。。。
if(唯一索引报错?)
抛异常,已经秒过了,回滚。。。
update goods set goods_num=goods_num-1 where goods_id=$goods_id and goods_num>0 ;
if(受影响行数<=0)
抛异常,商品秒完了,回滚。。。
该方法完美的解决了超卖与select排它锁导致的并发低的问题,并且4个sql缩减成2个sql语句。极大提升性能
- 秒杀核心设计(减库存部分)-防超卖与高并发
- 秒杀核心设计(减库存部分)-防超卖与高并发
- 秒杀核心设计——防止超卖、高并发与varnish详解
- mysql处理高并发,防止库存超卖,秒杀活动
- 二、高并发秒杀API之Dao层设计与实现
- 三、高并发秒杀API之Service层设计与实现
- 四、高并发秒杀API之Web层设计与实现
- Java开发面试:高并发秒杀系统如何设计与优化
- 高并发高性能仓库库存系统的架构设计
- 高并发高性能仓库库存系统的架构设计
- 高并发系统的设计及秒杀实践
- 关于高并发支付、秒杀的一些设计思路
- 高并发库存控制
- 高并发库存控制
- 高并发库存控制
- 高并发扣库存
- PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法
- PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法
- servlet的增删改查
- 软考之下午题
- 圆形头像
- Service通信(service介绍之二)
- Android 怎么使用Bitmap+Canvas 自适应屏幕
- 秒杀核心设计(减库存部分)-防超卖与高并发
- openstack Juno版部署记录
- UAC提升权限的细节
- C语言做的键盘操作的五子棋
- 第四章 冒泡排序法 潘璠
- 并查集的简单应用——HDU
- ARM 64位处理器架构ARMv8技术浅析
- C++线程基础
- 第十二篇 无聊的一天