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 相关文章推荐
一个程序下载的管理程序(一)
Oct 09 PHP
如何使用Strace调试工具
Jun 03 PHP
PHP对文件进行加锁、解锁实例
Jan 23 PHP
php去除字符串中空字符的常用方法小结
Mar 17 PHP
PHP SPL标准库之数据结构堆(SplHeap)简单使用实例
May 12 PHP
正确的PHP匹配UTF-8中文的正则表达式
May 13 PHP
joomla数据库操作示例代码
Jan 06 PHP
PHP实现搜索地理位置及计算两点地理位置间距离的实例
Jan 08 PHP
详解php框架Yaf路由重写
Jun 20 PHP
php检测mysql表是否存在的方法小结
Jul 20 PHP
Laravel框架查询构造器 CURD操作示例
Sep 04 PHP
laravel使用redis队列实例讲解
Mar 23 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
一个ORACLE分页程序,挺实用的.
2006/10/09 PHP
PHP执行批量mysql语句的解决方法
2013/05/02 PHP
Laravel框架实现发送短信验证功能代码
2016/06/06 PHP
利用PHP将图片转换成base64编码的实现方法
2016/09/13 PHP
php读取XML的常见方法实例总结
2017/04/25 PHP
thinkphp 框架数据库切换实现方法分析
2020/05/18 PHP
网站上面有这种切换效果
2006/06/26 Javascript
判断对象是否Window的实现代码
2012/01/10 Javascript
修改js Calendar日历控件 兼容IE9/谷歌/火狐
2013/01/04 Javascript
jQuery实现当按下回车键时绑定点击事件
2014/01/28 Javascript
JS遍历Json字符串中键值对先转成JSON对象再遍历
2014/08/15 Javascript
JavaScript中判断函数、变量是否存在
2015/06/10 Javascript
不同js异步函数同步的实现方法
2016/05/28 Javascript
Angular.Js的自动化测试详解
2016/12/09 Javascript
jQuery插件HighCharts实现气泡图效果示例【附demo源码】
2017/03/13 Javascript
JavaScript实现省市县三级级联特效
2017/05/16 Javascript
javaScript中"=="和"==="的区别详解
2018/03/16 Javascript
JS 实现缓存算法的示例(FIFO/LRU)
2018/03/20 Javascript
node前端模板引擎Jade之标签的基本写法
2018/05/11 Javascript
python比较两个列表大小的方法
2015/07/11 Python
python开发之thread实现布朗运动的方法
2015/11/11 Python
基于Python实现一个简单的银行转账操作
2016/03/06 Python
谈谈如何手动释放Python的内存
2016/12/17 Python
Python实现的破解字符串找茬游戏算法示例
2017/09/25 Python
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
2017/10/01 Python
Python时间戳使用和相互转换详解
2017/12/11 Python
pandas DataFrame 删除重复的行的实现方法
2019/01/29 Python
python opencv 实现读取、显示、写入图像的方法
2020/06/08 Python
Python requests上传文件实现步骤
2020/09/15 Python
12个不为大家熟知的HTML5设计小技巧
2016/06/02 HTML / CSS
国际金融专业自荐信
2014/07/05 职场文书
文言文辞职信
2015/02/28 职场文书
2015年秋季新学期寄语
2015/03/25 职场文书
民事申诉状范本
2015/05/20 职场文书
html5 录制mp3音频支持采样率和比特率设置
2021/07/15 Javascript
阿里云服务器部署RabbitMQ集群的详细教程
2022/06/01 Servers