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 MySQL应用中使用XOR运算加密算法分享
Aug 28 PHP
php中配置文件操作 如config.php文件的读取修改等操作
Jul 07 PHP
php将gd生成的图片缓存到memcache的小例子
Jun 05 PHP
使用php判断网页是否gzip压缩
Jun 25 PHP
PHP取二进制文件头快速判断文件类型的实现代码
Aug 05 PHP
php小技巧之过滤ascii控制字符
May 14 PHP
PHP简单获取视频预览图的方法
Mar 12 PHP
Laravel 5框架学习之Eloquent 关系
Apr 09 PHP
typecho插件编写教程(二):写一个新插件
May 28 PHP
Zend Framework教程之Loader以及PluginLoader用法详解
Mar 09 PHP
PHP Cookie学习笔记
Aug 23 PHP
Yii 框架控制器创建使用及控制器响应操作示例
Oct 14 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
php5.3 废弃函数小结
2010/05/16 PHP
PHP开发微信支付的代码分享
2014/05/25 PHP
对PHP语言认识上需要避免的10大误区
2014/06/12 PHP
JS实现很酷的EMAIL地址添加功能实例
2015/02/28 Javascript
javascript鼠标右键菜单自定义效果
2020/12/08 Javascript
JavaScript检测原始值、引用值、属性
2016/06/20 Javascript
一个简单的JavaScript Map实例(分享)
2016/08/03 Javascript
JS控制页面跳转时未请求要跳转的地址怎么回事
2016/10/14 Javascript
基于jQuery实现滚动切换效果
2016/12/02 Javascript
Bootstrap select下拉联动(jQuery cxselect)
2017/01/04 Javascript
Vue.js基础知识小结
2017/01/13 Javascript
JavaScript制作简易计算器(不用eval)
2017/02/05 Javascript
ES6新特性之数组、Math和扩展操作符用法示例
2017/04/01 Javascript
在node中如何使用 ES6
2017/04/22 Javascript
VueJS事件处理器v-on的使用方法
2017/09/27 Javascript
JS学习笔记之闭包小案例分析
2019/05/29 Javascript
ES6中let、const的区别及变量的解构赋值操作方法实例分析
2019/10/15 Javascript
JS面向对象之多选框实现
2020/01/17 Javascript
Python中的 is 和 == 以及字符串驻留机制详解
2019/06/28 Python
Python pandas自定义函数的使用方法示例
2019/11/20 Python
浅谈matplotlib默认字体设置探索
2021/02/03 Python
10张动图学会python循环与递归问题
2021/02/06 Python
Python 图片处理库exifread详解
2021/02/25 Python
HTML5自定义属性的问题分析
2019/08/16 HTML / CSS
地球鞋加拿大官网:Earth Shoes Canada
2020/11/17 全球购物
电气工程自动化求职信
2014/03/14 职场文书
超市中秋节促销方案
2014/03/21 职场文书
企业授权委托书范本
2014/04/02 职场文书
公司离职证明范本(汇总)
2014/09/10 职场文书
2014年党员整改措施
2014/10/24 职场文书
离婚代理词范文
2015/05/23 职场文书
锦旗赠语
2015/06/23 职场文书
重阳节主题班会
2015/08/17 职场文书
关于感恩的作文
2019/08/26 职场文书
k-means & DBSCAN 总结
2021/04/27 Python
redis实现排行榜功能
2021/05/24 Redis