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+dbfile开发小型留言本
Oct 09 PHP
php录入页面中动态从数据库中提取数据的实现
Oct 09 PHP
Discuz 6.0+ 批量注册用户名
Sep 13 PHP
php中防止SQL注入的最佳解决方法
Apr 25 PHP
PHP的构造方法,析构方法和this关键字详细介绍
Oct 22 PHP
PHP错误和异长常处理总结
Mar 06 PHP
PHPMailer发送HTML内容、带附件的邮件实例
Jul 01 PHP
详谈PHP文件目录基础操作
Nov 11 PHP
在PHP程序中使用Rust扩展的方法
Jul 03 PHP
PHP比较运算符的详细介绍
Sep 29 PHP
php set_include_path函数设置 include_path 配置选项
Oct 30 PHP
关于Laravel参数验证的一些疑与惑
Nov 19 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 session会话的安全性分析
2011/09/08 PHP
php使用date和strtotime函数输出指定日期的方法
2014/11/14 PHP
php读取远程gzip压缩网页的方法
2014/12/29 PHP
详解Window7 下开发php扩展
2015/12/31 PHP
Yii2汉字转拼音类的实例代码
2017/04/18 PHP
php双层循环(九九乘法表)
2017/10/23 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
PHP swoole和redis异步任务实现方法分析
2019/08/12 PHP
JavaScript 实现??打印?理
2007/04/28 Javascript
同一个表单 根据要求递交到不同页面的实现方法小结
2009/08/05 Javascript
正则表达式搭配js轻松处理json文本方便而老古
2013/02/17 Javascript
document.documentElement的一些使用技巧
2013/04/18 Javascript
javascript中取前n天日期的两种方法分享
2014/01/26 Javascript
Javascript+CSS实现影像卷帘效果思路及代码
2014/10/20 Javascript
Angular 中 select指令用法详解
2016/09/29 Javascript
基于Layer+jQuery的自定义弹框
2020/05/26 Javascript
Vue.js在使用中的一些注意知识点
2017/04/29 Javascript
关于预加载InstantClick的问题解决方法
2017/09/12 Javascript
JavaScript中的高级函数
2018/01/04 Javascript
layer弹出层全屏及关闭方法
2018/08/17 Javascript
js基于canvas实现时钟组件
2021/02/07 Javascript
[01:00:25]NB vs Secret 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
[03:02]2020完美世界城市挑战赛(秋季赛)总决赛回顾
2021/03/11 DOTA
在Python中实现贪婪排名算法的教程
2015/04/17 Python
Python实现视频下载功能
2017/03/14 Python
Python高级特性切片(Slice)操作详解
2018/09/27 Python
python sort、sort_index方法代码实例
2019/03/28 Python
LORAC官网:美国彩妆品牌
2019/08/27 全球购物
招商业务员岗位职责
2013/12/16 职场文书
社团文化节策划书
2014/02/01 职场文书
人资专员岗位职责
2014/04/04 职场文书
房产公证书
2015/01/23 职场文书
人民检察院起诉书
2015/05/20 职场文书
交通事故调解协议书
2015/05/20 职场文书
环保建议书作文300字
2015/09/14 职场文书
jupyter notebook保存文件默认路径更改方法汇总(亲测可以)
2021/06/09 Python