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 相关文章推荐
一个好用的分页函数
Nov 16 PHP
LotusPhp笔记之:基于ObjectUtil组件的使用分析
May 06 PHP
php去掉URL网址中带有PHPSESSID的配置方法
Jul 08 PHP
php 伪造ip以及url来路信息方法汇总
Nov 25 PHP
THINKPHP2.0到3.0有哪些改进之处
Jan 04 PHP
Symfony数据校验方法实例分析
Jan 26 PHP
33道php常见面试题及答案
Jul 06 PHP
CI(Codeigniter)的Setting增强配置类实例
Jan 06 PHP
PHP随机获取未被微信屏蔽的域名(微信域名检测)
Mar 19 PHP
详谈php中 strtr 和 str_replace 的效率问题
May 14 PHP
php实现留言板功能(会话控制)
May 23 PHP
详解PHP服务器如何在有限的资源里最大提升并发能力
May 25 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
索尼SONY ICF-SW7600GR电路分析与改良
2021/03/02 无线电
php+ajax实现无刷新分页的方法
2014/11/04 PHP
php查询相似度最高的字符串的方法
2015/03/12 PHP
PHP实现原比例生成缩略图的方法
2016/02/03 PHP
10个对初学者非常有用的PHP技巧
2016/04/06 PHP
根据对象的某一属性进行排序的js代码(如:name,age)
2010/08/10 Javascript
jquery遍历checkbox的注意事项说明
2014/02/21 Javascript
js判断登陆用户名及密码是否为空的简单实例
2016/05/16 Javascript
详解jQuery中ajax.load()方法
2017/01/25 Javascript
nodejs开发——express路由与中间件
2017/03/24 NodeJs
layui文件上传实现代码
2017/05/20 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)
2020/10/15 Javascript
JavaScript基于SVG的图片切换效果实例代码
2020/12/15 Javascript
Python转码问题的解决方法
2008/10/07 Python
使用Python生成url短链接的方法
2015/05/04 Python
Python数据类型中的“冒号“[::]——分片与步长操作示例
2018/01/24 Python
PyCharm代码整体缩进,反向缩进的方法
2018/06/25 Python
将string类型的数据类型转换为spark rdd时报错的解决方法
2019/02/18 Python
python实现动态创建类的方法分析
2019/06/25 Python
python实现代码统计器
2019/09/19 Python
python中温度单位转换的实例方法
2020/12/27 Python
Python3+Django get/post请求实现教程详解
2021/02/16 Python
服装销售人员求职自我评价
2013/09/26 职场文书
中学生爱国演讲稿
2013/12/31 职场文书
公司企业表扬信
2014/01/11 职场文书
图书馆志愿者活动总结
2014/06/27 职场文书
学雷锋的心得体会
2014/09/04 职场文书
安全员岗位职责
2015/02/10 职场文书
2015年保送生自荐信
2015/03/24 职场文书
2016暑期师德培训心得体会
2016/01/09 职场文书
2019入党申请书范文3篇
2019/08/21 职场文书
Pytorch中TensorBoard及torchsummary的使用详解
2021/05/12 Python
Python中OpenCV实现查找轮廓的实例
2021/06/08 Python
CSS控制继承中的height能变为可继承吗
2022/06/10 HTML / CSS
Nginx跨域问题解析与解决
2022/08/05 Servers