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 相关文章推荐
用Socket发送电子邮件
Oct 09 PHP
PHP脚本数据库功能详解(下)
Oct 09 PHP
PHP 分页类(模仿google)-面试题目解答
Sep 13 PHP
PHP数组内存耗用太多问题的解决方法
Apr 05 PHP
php在多维数组中根据键名快速查询其父键以及父键值的代码
May 07 PHP
基于ubuntu下nginx+php+mysql安装配置的具体操作步骤
Apr 28 PHP
深入php处理整数函数的详解
Jun 09 PHP
PHP迭代器的内部执行过程详解
Nov 12 PHP
thinkPHP下的widget扩展用法实例分析
Dec 26 PHP
PHP中如何判断exec函数执行成功?
Aug 04 PHP
php array_values 返回数组的所有值详解及实例
Nov 12 PHP
php判断str字符串是否是xml格式数据的方法示例
Jul 26 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中的PDO类
2015/07/06 PHP
php给图片加文字水印
2015/07/31 PHP
PHP的Yii框架中创建视图和渲染视图的方法详解
2016/03/29 PHP
PHP数组实例详解
2016/06/26 PHP
php基于dom实现的图书xml格式数据示例
2017/02/03 PHP
js 控制图片大小核心讲解
2013/10/09 Javascript
Javascript闭包用法实例分析
2015/01/23 Javascript
jQuery选择id属性带有点符号元素的方法
2015/03/17 Javascript
js实时获取窗口大小变化的实例代码
2016/11/18 Javascript
jsTree使用记录实例
2016/12/01 Javascript
JavaScript实现的浏览器下载文件的方法
2017/08/09 Javascript
layui 实现表格某一列显示图标
2019/09/19 Javascript
Vue.js使用axios动态获取response里的data数据操作
2020/09/08 Javascript
python实现探测socket和web服务示例
2014/03/28 Python
Python 实现链表实例代码
2017/04/07 Python
python数据分析数据标准化及离散化详解
2018/02/26 Python
Python实现迭代时使用索引的方法示例
2018/06/05 Python
Numpy 改变数组维度的几种方法小结
2018/08/02 Python
Python 保持登录状态进行接口测试的方法示例
2019/08/06 Python
Pytorch对Himmelblau函数的优化详解
2020/02/29 Python
在服务器上安装python3.8.2环境的教程详解
2020/04/26 Python
django正续或者倒序查库实例
2020/05/19 Python
查看keras的默认backend实现方式
2020/06/19 Python
详解Python中的文件操作
2021/01/14 Python
HTML5页面音视频在微信和app下自动播放的实现方法
2016/10/20 HTML / CSS
AURALog面试题软件测试方面
2013/10/22 面试题
教师岗位职责范本
2013/12/29 职场文书
行政部总经理岗位职责
2014/01/04 职场文书
法院干警四风问题个人对照检查材料思想汇报
2014/10/07 职场文书
2015年度酒店客房部工作总结
2015/05/25 职场文书
红色经典观后感
2015/06/18 职场文书
教师远程培训心得体会
2016/01/09 职场文书
六五普法心得体会2016
2016/01/21 职场文书
2016基督教会圣诞节开幕词
2016/03/04 职场文书
作文之亲情600字
2019/09/23 职场文书
gtx1650怎么样 gtx1650显卡相当于什么级别
2022/04/08 数码科技