PHP开发中解决并发问题的几种实现方法分析


Posted in PHP onNovember 13, 2017

本文实例讲述了PHP开发中解决并发问题的几种实现方法。分享给大家供大家参考,具体如下:

对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了

在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制。

方案一:使用文件锁排它锁

flock函数用于获取文件的锁,这个锁同时只能被一个线程获取到,其它没有获取到锁的线程要么阻塞,要么获取失败

在获取到锁的时候,先查询库存,如果库存大于0,则进行下订单操作,减库存,然后释放锁

方案二:使用Mysql数据库提供的悲观锁

Innodb存储引擎支持行级锁,当某行数据被锁定时,其他进程不能对这行数据进行操作

先查询并锁定行:

select stock_num from table where id=1 for update
if(stock_num > 0){
//下订单
update table set stock_num=stock-1 where id=1
}

方案三:使用队列

将用户的下单请求依次存入一个队列中,后台用一个单独的进程处理队列中的下单请求

方案四:使用Redis

redis的操作都是原子性的,可以将商品的库存存入redis中,下单之前对库存进行decr操作,如果返回的值大于等于0等可以下单,否则不能下单,这种方式效率较高

if(redis->get('stock_num') > 0){
 stock_num = redis->decr('stock_num')
 if(stock_num >= 0){
 //下订单
 }else{
 //库存不足
 }
}else{
//库存不足
}

其他并发问题:

在现实应用中,很多情况下会把数据存入缓存,当缓存失效时,去数据库取数据并重新设置缓存,如果这时并发量很大,会有很多进程同时去数据库取数据,导致很多请求

穿透到数据库,而使数据库奔溃,这里可用文件锁来解决

$data = $cache->get('key');
if(!$data){
  $fp = fopen('lockfile');
  if(flock($fp, LOCK_EX)){
    $data = $cache->get('key');//拿到锁后再次检查缓存,这时可能已经有了
    if(!$data){
      $data = mysql->query();
      $cache->set('key', $data);
    }
    flock($fp, LOCK_UN);
  }
  fclose($fp);
}

说白了,要解决并发问题就必须要加锁,各种方案的本质都是加锁

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP模板引擎SMARTY
Oct 09 PHP
php桌面中心(二) 数据库写入
Mar 11 PHP
php 多个submit提交表单 处理方法
Jul 07 PHP
PHP类中Static方法效率测试代码
Oct 17 PHP
具有时效性的php加密解密函数代码
Jun 19 PHP
php对csv文件的读取,写入,输出下载操作详解
Aug 10 PHP
php版小黄鸡simsimi聊天机器人接口分享
Jan 26 PHP
php中$_GET与$_POST过滤sql注入的方法
Nov 03 PHP
THINKPHP支持YAML配置文件的设置方法
Mar 17 PHP
thinkPHP3.1验证码的简单实现方法
Apr 22 PHP
laravel自定义分页效果
Jul 23 PHP
PHP数组Key强制类型转换实现原理解析
Sep 01 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
Nov 13 #PHP
kindeditor 加入七牛云上传的实例讲解
Nov 12 #PHP
Thinkphp5 微信公众号token验证不成功的原因及解决方法
Nov 12 #PHP
PHP 断点续传实例详解
Nov 11 #PHP
PHP+AJAX 投票器功能
Nov 11 #PHP
PHP实现双链表删除与插入节点的方法示例
Nov 11 #PHP
PHP实现基于栈的后缀表达式求值功能
Nov 10 #PHP
You might like
zf框架的registry(注册表)使用示例
2014/03/13 PHP
php实现快速对二维数组某一列进行组装的方法小结
2019/12/04 PHP
JavaScript中“+=”的应用
2007/02/02 Javascript
jQuery1.4.2与老版本json格式兼容的解决方法
2011/02/12 Javascript
图片img的src不变让浏览器重新加载实现方法
2013/03/29 Javascript
js实现表单多按钮提交action的处理方法
2015/10/24 Javascript
javascript正则表达式中分组详解
2016/07/17 Javascript
Bootstrap使用基础教程详解
2016/09/05 Javascript
Node.js的基本知识简单汇总
2016/09/19 Javascript
Jil,高效的json序列化和反序列化库
2017/02/15 Javascript
js实现无缝滚动图
2017/02/22 Javascript
微信小程序 wx.request方法的异步封装实例详解
2017/05/18 Javascript
利用jquery去掉时光轴头尾部线条的方法实例
2017/06/16 jQuery
jQuery事件_动力节点Java学院整理
2017/07/05 jQuery
vue addRoutes路由动态加载操作
2020/08/04 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
[41:52]2018DOTA2亚洲邀请赛3月29日小组赛B组Effect VS Secret
2018/03/30 DOTA
django之常用命令详解
2016/06/30 Python
Python连接PostgreSQL数据库的方法
2016/11/28 Python
使用python 和 lint 删除项目无用资源的方法
2017/12/20 Python
Python基于最小二乘法实现曲线拟合示例
2018/06/14 Python
python 机器学习之支持向量机非线性回归SVR模型
2019/06/26 Python
django 信号调度机制详解
2019/07/19 Python
Python Opencv实现单目标检测的示例代码
2020/09/08 Python
Django Form常用功能及代码示例
2020/10/13 Python
Python 实现3种回归模型(Linear Regression,Lasso,Ridge)的示例
2020/10/15 Python
HTML5输入框下拉菜单功能的示例代码
2020/09/08 HTML / CSS
PUMA澳大利亚官方网站:德国运动品牌
2018/10/19 全球购物
法律专业个人实习自我鉴定
2013/09/23 职场文书
临床医学专业个人的自我评价
2013/09/27 职场文书
舞蹈兴趣小组活动总结
2014/07/07 职场文书
民主评议政风行风活动心得体会
2014/10/29 职场文书
2014年学生会部门工作总结
2014/11/07 职场文书
2014年节能工作总结
2014/12/18 职场文书
2015年电信员工工作总结
2015/05/26 职场文书
Golang并发工具Singleflight
2022/05/06 Golang