mysql防止商品超卖_避免商品超卖的4种方案
原始方案(失败):在每次下订单前我们判断促销商品的数量够不够,不够不允许下订单,更改库存量时加上一个条件,只更改商品库存大于0的商品的库存,当时我们使用ab进行压力测试,当并发超过500,访问量超过2000时,还是会出现超卖现象。
public functionbuyOne()
{$shop = Shop::find(1);if ($shop->number > 0) {
DB::update("update shop set number = number - 1 where id = 1");
}
}
第1种方案:使用mysql的事务加排他锁来解决,首先我们选择数据库的存储引擎为innoDB,使用的是排他锁实现的,刚开始的时候我们测试了下共享锁,发现还是会出现超卖的现象。有个问题是,当我们进行高并发测试时,对数据库的性能影响很大,导致数据库的压力很大。
//2.利用数据库的forupdate来加锁(在数量少的情况下并不会出现问题,但是当并发达到(ab -n 1000 -c 200),
//就会出现请求非2XX的响应增多,1000 失败了 60)time per request 65.195
//在高并发的情况下,会导致数据库连接数不够,部分php获取不到连接而报错,或者是超过等待时间而报错
public functionindexMysql()
{
DB::beginTransaction();//通过for update 加排它锁
$shop = DB::table('shop')->where('id', '=', 1)->lockForUpdate()->first();if ($shop->number > 0) {if (DB::update("update shop set number = number - 1 where id = 1")) {
DB::commit();
}else{
DB::rollBack();//回滚并重试
usleep(100000);$this->indexMysql();
}
}else{
DB::commit();
}
}
第2种方案:使用文件锁实现。当用户抢到一件促销商品后先触发文件锁,防止其他用户进入,该用户抢到促销品后再解开文件锁,放其他用户进行操作。这样可以解决超卖的问题,但是会导致文件得I/O开销很大。
第3种方案:使用redis的setnx来实现锁机制。但是并发大的情况下,锁的争夺会变多,导致响应越来越慢。(与第四种方案类似)
//在数量少的情况下并不会出现问题,但是当并发达到(ab -n 1000 -c 200 就会出现请求非2XX的响应增多,1000 失败了 54) time per request 127.575
public functionindex()
{//测试并发超卖现象
if (Redis::setnx(self::KEY, 1)) {//拿到了锁
$this->buy();
}else{usleep(100000);//等会再去拿锁
//Log::info("未争夺到锁,睡眠100ms");
$this->index();
}
}
private functionbuy()
{$shop = Shop::find(1);if ($shop->number > 0) {$shop->number --;$shop->save();
}
Redis::del(self::KEY);
}
第4种方案:redis的队列来实现。将要促销的商品数量以队列的方式存入redis中,每当用户抢到一件促销商品则从队列中删除一个数据,确保商品不会超卖。这个操作起来很方便,而且效率极高
//4.使用redis队列来,用户过来直接入队列,然后再将操作更新到数据库
//最佳体验(redis pconnect 9.481s, 无丢失, 无框架)
public functionpush()
{//入队列
Redis::lpush(self::QUEUE, 1);
}
//脚本调用pop方法 * * * * * php xxx.php
public functionpop()
{while (($key = Redis::rpop(self::QUEUE))) {$shop = Shop::find(1);if ($shop->number > 0) {
DB::update("update shop set number = number - 1 where id = 1")
}
}
}
mysql防止商品超卖_避免商品超卖的4种方案相关推荐
- mysql实现商品自动下架_关于商品的上架和下架的操作
①建库建表 插入数据 ②创建工程(LibraryManage),导入Tomcat,升级junit,导入jar包 < !-- https://mvnrepository.com/artifact/ ...
- mysql商品规格设计_关于商品规格(SKU)的设置
SKU定义和正确发布 SKU=stock keeping unit(库存量单位),SKU即库存进出计量的单位, 可以是以件.盒.托盘等为单位.在服装.鞋类商品中使用最多最普遍. 例如纺织品中一个SKU ...
- python语言求商品的总价_计算商品总价?
如何通过checkbox计算选中商品得价格? {{item.book_title}} ¥{{item.book_price}} 共 {{mount}} 本 合计 ¥{{total}} 提交订单 imp ...
- arm cpu 超频_树莓派 400 超频方法介绍
对树莓派 400 进行超频非常容易实现.散热上,树莓派 400 设计了一个面积很大的被动散热器,这很有用.无需额外的主动降温就可以应对超频的散热需求. 尽管有些用户通过配置,让树莓派 400 超频到了 ...
- mysql内链查询写法_网站内链优化与几种常见的结构优化方法
在互联网的海洋沉淀了这么多年,经常会看见很多新人学着学着就放弃了,甚至有人还说做seo还不如去工地上班.真的是这样吗?其实不是这样的,很多行业有进人进来,就有老人离开,这属于自然规律.许多的站长做着做 ...
- mysql in and in_完美解决mysql in条件语句只读取一条信息问题的2种方案
今天同事在编写MYSQL查询语句时遇到一个很奇怪的问题,使用mysql多表查询,一个表中的某个字段作为另一表的in查询条件,只能读取一条信息,而直接用数字的话可以正常读取 SQL语句如下: selec ...
- mysql 5亿数据 查询_日均5亿查询量的京东订单中心,为什么舍MySQL用ES?
来源:京东技术订阅号(ID:jingdongjishu) 京东到家订单中心系统业务中,无论是外部商家的订单生产,或是内部上下游系统的依赖,订单查询的调用量都非常大,造成了订单数据读多写少的情况.我们把 ...
- mysql 高并发扣除库存_【并发】mysql处理高并发,防止库存超卖
先来就库存超卖的问题作描述:一般电子商务网站都会遇到如团购.秒杀.特价之类的活动,而这样的活动有一个共同的特点就是访问量激增.上千甚至上万人抢购 一个商品.然而,作为活动商品,库存肯定是很有限的,如何 ...
- 避免商品超卖的4种方案
避免商品超卖的4种方案(以下是一些核心思路) 原始方案(失败):在每次下订单前我们判断促销商品的数量够不够,不够不允许下订单,更改库存量时加上一个条件,只更改商品库存大于0的商品的库存,当时我们使用a ...
- 超卖频发or商品滞销?压倒卖家的最后一根稻草竟是库存!
超卖频发or商品滞销?压倒卖家的最后一根稻草竟是库存! 云南逸神生态茶业有限公司便是一家从最初的单体销售到目前的生产.加工.销售一体化经营,并拥有60多家遍布云南省内.省外城市的直营专卖店.想要发展壮 ...
最新文章
- Linux管道编程实例
- 关于扫描的一个比较好的网站
- RUNOOB python练习题33 使用join方法实现用逗号分隔列表
- 基于SpringMVC+EasyPoi,采用Excel模板方式实现Excel在线预览和导出(2021版)
- Java 找到并返回一组字符串中第一个不为空的字符串
- [Head First设计模式]云南米线馆中的设计模式——模版方法模式
- paip.执行shell cmd 命令uapi java php python总结
- Java期末考试知识点复习
- cad批量页码lisp_源代码:批量改页码(加前缀)及提取属性块
- xshell 使用教程
- Starting Programe
- 为资产分类定义折旧范围_2广东省农村集体经济组织固定资产分类及折旧办法(4月15日)...
- 公众号推送长图最佳尺寸_微信公众平台图片尺寸是多少
- Java实现PDF打印的解决方案
- VC/MFC如何设置对话框、static背景颜色
- 计算机软件图标乱码,Win7系统桌面快捷图标名称显示乱码如何解决
- Mac 关闭 Adobe Creative Cloud
- 利用 conda install --use-local 安装 解决 Tensorflow: illegal instruction (core dumped)
- 计算机管理mmc无法,mmc无法创建管理单元解决方法
- Linux中__setup()实现原理以及源码分析