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使用eAccelerator的API开发详解
Jun 09 PHP
php使用多个进程同时控制文件读写示例
Feb 28 PHP
PHP 只允许指定IP访问(允许*号通配符过滤IP)
Jul 08 PHP
smarty内置函数config_load用法实例
Jan 22 PHP
自己写的php curl库实现整站克隆功能
Feb 12 PHP
PHP使用内置函数生成图片的方法详解
May 09 PHP
基于php判断客户端类型
Oct 14 PHP
php连接MSsql server的五种方法总结
Mar 04 PHP
ThinkPHP框架使用redirect实现页面重定向的方法实例分析
Apr 12 PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
Feb 13 PHP
php统计数组不同元素的个数的实例方法
Sep 26 PHP
Laravel5.1 框架表单验证操作实例详解
Jan 07 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
简单谈谈php中的unicode和utf8编码
2015/06/10 PHP
PHP导入导出Excel代码
2015/07/07 PHP
PHP利用百度ai实现文本和图片审核
2019/05/08 PHP
laravel实现按月或天或小时统计mysql数据的方法
2019/10/09 PHP
一个简单的js渐显(fadeIn)渐隐(fadeOut)类
2010/06/19 Javascript
给jqGrid数据行添加修改和删除操作链接(之一)
2011/11/04 Javascript
Event altKey,ctrlKey,shiftKey属性解析
2013/12/18 Javascript
用jquery实现的一个超级简单的下拉菜单
2014/05/18 Javascript
node.js中的fs.close方法使用说明
2014/12/17 Javascript
jQuery 处理页面的事件详解
2015/01/20 Javascript
Javascript中的arguments与重载介绍
2015/03/15 Javascript
JQuery包裹DOM节点的方法
2015/06/11 Javascript
jQuery的事件委托实例分析
2015/07/15 Javascript
jquery结婚电子请柬特效源码分享
2015/08/21 Javascript
NodeJS处理Express中异步错误
2017/03/26 NodeJs
关于react-router的几种配置方式详解
2017/07/24 Javascript
jQuery实现的粘性滚动导航栏效果实例【附源码下载】
2017/10/19 jQuery
vue的style绑定background-image的方式和其他变量数据的区别详解
2018/09/03 Javascript
微信小程序导航栏跟随滑动效果的实现代码
2019/05/14 Javascript
vue 使用插槽分发内容操作示例【单个插槽、具名插槽、作用域插槽】
2020/03/06 Javascript
js实现九宫格抽奖
2020/03/19 Javascript
Python实现爬取百度贴吧帖子所有楼层图片的爬虫示例
2018/04/26 Python
详解Python3注释知识点
2019/02/19 Python
Python实现html转换为pdf报告(生成pdf报告)功能示例
2019/05/04 Python
python的几种矩阵相乘的公式详解
2019/07/10 Python
Python Django2 model 查询介绍(条件、范围、模糊查询)
2020/03/16 Python
Python pexpect模块及shell脚本except原理解析
2020/08/03 Python
python脚本第一行如何写
2020/08/30 Python
python爬虫实现爬取同一个网站的多页数据的实例讲解
2021/01/18 Python
护理学专业推荐信
2013/12/03 职场文书
理工学院学生自我鉴定
2014/02/23 职场文书
演讲稿开场白台词
2014/08/25 职场文书
罚站检讨书
2015/01/29 职场文书
大学生党员暑假实践(活动总结)
2019/08/21 职场文书
python 爬取华为应用市场评论
2021/05/29 Python
MySQL批量更新不同表中的数据
2022/05/11 MySQL