`

(转)秒杀核心设计(减库存部分)-防超卖与高并发

阅读更多

重点设计在数据库层面。

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语句。极大提升性能

分享到:
评论

相关推荐

    基于springmvc高并发秒杀系统

    代码设计风格基于RESTful,以c3p0作为连接池,Redis数据库为媒介实现高并发技术。其中,对于相关的DAO,Service操作,均添加了Junit单元测试实例。 开发文档 一、业务分析 1.秒杀系统业务流程 2.秒杀业务的核心...

    高并发场景防止库存数量超卖少卖

    在高并发电商场景下,商品超卖(即销售量超出库存)是常见问题,主要由并发扣减库存导致。常规做法是在扣减库存前检查库存充足性,但面对大量并发请求时,这种方法可能失效。为此,可采用以下几种策略: 悲观锁:在...

    解决高并发环境下Redis连接超时与超卖问题

    这个Demo演示了使用redis乐观锁机制解决高并发环境下出现连接超时与超卖(库存出现负数)情况的解决办法。

    高性能电商秒杀解决方案

    • 秒杀的商品一般库存较少,只有少数用户能够购买,要控制好库存,防止超卖; • 整个系统关键在于支撑短时间内的高并发,降低数据库压力,业务和普通商品购买区别不大 秒杀系统性能瓶颈在于数据库无法处理并发访问...

    Spring Boot + redis解决商品秒杀库存超卖

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

    PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)

    上一篇文章聊了一下使用Redis事务来解决高并发商品超卖问题,今天我们来聊一下使用Redis链表来解决高并发商品超卖问题。 实现原理 使用redis链表来做,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,...

    seckill-master-lkk.zip

    - 秒杀的商品一般库存较少,只有少数用户能够购买,要控制好库存,防止超卖; - 整个系统关键在于支撑短时间内的高并发,降低数据库压力,业务和普通商品购买区别不大 秒杀系统性能瓶颈在于数据库无法处理并发...

    使用rabbitmq解决超卖问题

    高并发环境下是很容易发生库存的情况,这个demo演示了使用RabbitMQ解决高并发环境下超卖问题。

    微服务 Spring Boot 整合Redis 秒杀 ,全局唯一ID,乐观锁解决库存超卖,Jmeter 测试 每秒千万级并发

    微服务 Spring Boot 整合Redis 秒杀 ,全局唯一ID,乐观锁解决库存超卖,Jmeter 测试 每秒千万级并发

    redis令牌机制实现秒杀系统

    间有限的情况下导致的一个高并发以及高并发所带来的库存超卖的问题。 秒杀需要解决的问题: 1) 库存超卖 解决方案: 1) 悲观锁:synchronize 、 Lock 2) 乐观锁:数据库乐观锁版本号控制 2) 高并发情况下系统压力...

    秒杀系统(前端、后端、中间件完整代码)

    3、系统压测:JMeter,目的:发现秒杀系统的问题(低并发并不会出现问题,但是在高并发会出现很多问题,比如:超卖问题) 如何处理高并发: (1)缓存 (2)异步 (3)安全 4、页面优化(商品会不会出现超卖、性能...

    一个微服务 Spring Boot 整合Redis 秒杀 ,全局唯一ID,乐观锁解决库存超卖,Jmeter 测试 每秒千万级并发

    一个微服务 Spring Boot 整合Redis 秒杀 ,全局唯一ID,乐观锁解决库存超卖,Jmeter 测试 每秒千万级并发 项目

    redis-demo:spring boot高并发秒杀测试

    redis高并发秒杀测试测试项目: : 准备使用docker-compose命令启动redis服务器(可以用其他方式启动) idea启动测试项目jmeter测试脚本 重现秒杀时出现的超卖问题核心测试代码如下: /** * 用于测试redis秒杀 */@...

    高并发秒杀架构模型设计附源码案例

    本期我们就来探讨一下这个问题:分析秒杀的业务场景,最重要的有一点就是超卖问题,假如备货只有100个,但是最终超卖了200,一般来讲秒杀系统的价格都比较低,如果超卖将严重影响公司的财产利益,因此首当其冲的就是...

    PHP+Redis事务解决高并发下商品超卖问题(推荐)

    主要介绍了PHP+Redis事务解决高并发下商品超卖问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

    巴黎银行-全球-投资策略-石油产品超卖,贱金属富裕-0607-8页.pdf

    巴黎银行-全球-投资策略-石油产品超卖,贱金属富裕-0607-8页.pdf

    第8讲:分布式锁的原理及应用&秒杀设计实现.pdf

    用户下单库存超卖问题 3 为什么要用分布式锁?-- 业务场景-2 用户下单库存超卖问题 4 为什么要用分布式锁?-- 业务场景-2 用户下单库存超卖问题 APP快速连续点击会向服务器连续发起请求,导致数据库出现重复数据(非...

    秒杀系统B站编程不良人

    - 严格防止超卖:库存100件你卖了120件,等着辞职吧 - 防止黑产:防止不怀好意的人群通过各种技术手段把你本该下发给群众的利益全收入了囊中。 - 保证用户体验:高并发下,别网页打不开了,支付不成功了,购物车进...

    蚂蚁课堂-第四期-基于SpringCloud构建微服务电商项目

    |____032-秒杀系统设计-防止库存超卖问题.rar |____031-秒杀系统设计-技术方案讨论.rar |____030-微服务安全架构平台-基于令牌实现接口权限控制和责任链模式重构.rar ...... ____008-会员服务唯一登陆实现.rar |____...

Global site tag (gtag.js) - Google Analytics