php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题


Posted in PHP onJune 19, 2014

我们知道数据库处理sql是一条条处理的,假设购买商品的流程是这样的:

sql1:查询商品库存

if(库存数量 > 0)
{
  //生成订单...
  sql2:库存-1
}

当没有并发时,上面的流程看起来是如此完美,假设同时两个人下单,而库存只有1个了,在sql1阶段两个人查询到的库存都是>0的,于是最终都执行了sql2,库存最后变为-1,超售了,要么补库存,要么等用户投诉吧。

解决这个问题比较流行的思路:

1.用额外的单进程处理一个队列,下单请求放到队列里,一个个处理,就不会有并发的问题了,但是要额外的后台进程以及延迟问题,不予考虑。

2.数据库乐观锁,大致的意思是先查询库存,然后立马将库存+1,然后订单生成后,在更新库存前再查询一次库存,看看跟预期的库存数量是否保持一致,不一致就回滚,提示用户库存不足。

3.根据update结果来判断,我们可以在sql2的时候加一个判断条件update ... where 库存>0,如果返回false,则说明库存不足,并回滚事务。

4.借助文件排他锁,在处理下单请求的时候,用flock锁定一个文件,如果锁定失败说明有其他订单正在处理,此时要么等待要么直接提示用户"服务器繁忙"

本文要说的是第4种方案,大致代码如下:

阻塞(等待)模式

<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX))
{
  //..处理订单
  flock($fp,LOCK_UN);
}
fclose($fp);
?>

非阻塞模式

<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX | LOCK_NB))
{
  //..处理订单
  flock($fp,LOCK_UN);
}
else
{
  echo "系统繁忙,请稍后再试";
}

fclose($fp);
?>
PHP 相关文章推荐
深入理解PHP之数组(遍历顺序)  Laruence原创
Jun 13 PHP
php+ajax实时输入自动搜索匹配的方法
Dec 26 PHP
PHP实现的下载远程图片自定义函数分享
Jan 28 PHP
PHP strtotime函数用法、实现原理和源码分析
Feb 04 PHP
PHP也能干大事 随机函数
Apr 14 PHP
php实现搜索一维数组元素并删除二维数组对应元素的方法
Jul 06 PHP
如何解决PHP无法实现多线程的问题
Sep 25 PHP
Yii2中关联查询简单用法示例
Aug 10 PHP
thinkPHP模板中函数的使用方法示例
Nov 30 PHP
thinkPHP5分页功能实现方法分析
Oct 25 PHP
PHP 实现手机端APP支付宝支付功能
Jun 07 PHP
Yii2框架操作数据库的方法分析【以mysql为例】
May 27 PHP
PHP base64编码后解码乱码的解决办法
Jun 19 #PHP
PHP安全的URL字符串base64编码和解码
Jun 19 #PHP
PHP中的多行字符串传递给JavaScript的两种方法
Jun 19 #PHP
ThinkPHP模板引擎之导入资源文件方法详解
Jun 18 #PHP
ThinkPHP CURD方法之field方法详解
Jun 18 #PHP
ThinkPHP CURD方法之data方法详解
Jun 18 #PHP
ThinkPHP CURD方法之order方法详解
Jun 18 #PHP
You might like
PHP中=赋值操作符对不同数据类型的不同行为
2011/01/02 PHP
解析php DOMElement 操作xml 文档的实现代码
2013/05/10 PHP
php获取根域名方法汇总
2014/10/28 PHP
PHP对文件进行加锁、解锁实例
2015/01/23 PHP
php实现概率性随机抽奖代码
2016/01/02 PHP
js玩一玩WSH吧
2007/02/23 Javascript
javascript 无提示关闭窗口脚本
2009/08/17 Javascript
JavaScript学习笔记(十七)js 优化
2010/02/04 Javascript
javascript下4个跨浏览器必备的函数
2010/03/07 Javascript
js 代码优化点滴记录
2012/02/19 Javascript
文本框输入时 实现自动提示(像百度、google一样)
2012/04/05 Javascript
用JavaScript实现一个代码简洁、逻辑不复杂的多级树
2014/05/23 Javascript
jquery+CSS3模拟Path2.0动画菜单效果代码
2015/08/31 Javascript
Js与Jq获取浏览器和对象值的方法
2016/03/18 Javascript
Javascript实现通过选择周数显示开始日和结束日的实现代码
2016/05/30 Javascript
BootStrap+Angularjs+NgDialog实现模式对话框
2016/08/24 Javascript
微信小程序  TLS 版本必须大于等于1.2问题解决
2017/02/22 Javascript
d3.js入门教程之数据绑定详解
2017/04/28 Javascript
带你快速理解javascript中的事件模型
2017/08/14 Javascript
js读取本地文件的实例
2017/12/22 Javascript
详解React中合并单元格的正确写法
2019/01/08 Javascript
原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作
2019/02/27 jQuery
Vue中axios的封装(报错、鉴权、跳转、拦截、提示)
2019/08/20 Javascript
LayUi使用switch开关,动态的去控制它是否被启用的方法
2019/09/21 Javascript
基于JavaScript的数据结构队列动画实现示例解析
2020/08/06 Javascript
[06:53]2018DOTA2国际邀请赛寻真——勇于创新的Vici Gaming
2018/08/14 DOTA
如何利用Fabric自动化你的任务
2016/10/20 Python
python利用ffmpeg进行录制屏幕的方法
2019/01/10 Python
使用Python实现Wake On Lan远程开机功能
2020/01/22 Python
python使用for...else跳出双层嵌套循环的方法实例
2020/05/17 Python
《蒲公英》教学反思
2014/02/28 职场文书
无子女夫妻离婚协议书(4篇)
2014/10/20 职场文书
圣贤教育改变命运观后感
2015/06/16 职场文书
单独二胎证明
2015/06/24 职场文书
初二物理教学反思
2016/02/19 职场文书
Redis监控工具RedisInsight安装与使用
2022/03/21 Redis