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程序
Oct 09 PHP
php类常量的使用详解
Jun 08 PHP
php批量上传的实现代码
Jun 09 PHP
php中实现获取随机数组列表的自定义函数
Apr 02 PHP
php判断文件夹是否存在不存在则创建
Apr 09 PHP
护卫神php套件 php版本升级方法(php5.5.24)
May 10 PHP
php编程每天必学之验证码
Mar 03 PHP
PHP对象相关知识总结
Apr 09 PHP
php自定义函数实现统计中文字符串长度的方法小结
Apr 15 PHP
PHP微信支付结果通知与回调策略分析
Jan 10 PHP
tp5递归 无限级分类详解
Oct 18 PHP
laravel框架中控制器的创建和使用方法分析
Nov 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
php判断手机访问还是电脑访问示例分享
2014/01/20 PHP
PHP实现即时输出、实时输出内容方法
2015/05/27 PHP
JS图片自动轮换效果实现思路附截图
2014/04/30 Javascript
谷歌浏览器调试JavaScript小技巧
2014/12/29 Javascript
理解javascript定时器中的setTimeout与setInterval
2016/02/23 Javascript
简单实现js间歇或无缝滚动效果
2016/06/29 Javascript
vue中改变选中当前项的显示隐藏或者状态的实现方法
2018/02/08 Javascript
利用adb shell和node.js实现抖音自动抢红包功能(推荐)
2018/02/22 Javascript
搭建element-ui的Vue前端工程操作实例
2018/02/23 Javascript
原生JS实现的简单小钟表功能示例
2018/08/30 Javascript
JavaScript实现新年倒计时效果
2018/11/17 Javascript
微信小程序canvas.drawImage完全显示图片问题的解决
2018/11/30 Javascript
Vue项目中使用better-scroll实现一个轮播图自动播放功能
2018/12/03 Javascript
在博客园博文中添加自定义右键菜单的方法详解
2020/02/05 Javascript
在Vue中使用Viser说明(基于AntV-G2可视化引擎)
2020/10/28 Javascript
[02:41]DOTA2英雄基础教程 谜团
2013/12/10 DOTA
Python创建模块及模块导入的方法
2015/05/27 Python
Python入门学习之字符串与比较运算符
2015/10/12 Python
详解Python pygame安装过程笔记
2017/06/05 Python
python3+PyQt5实现文档打印功能
2018/04/24 Python
python生成1行四列全2矩阵的方法
2018/08/04 Python
Django框架自定义模型管理器与元选项用法分析
2019/07/22 Python
Django 使用easy_thumbnails压缩上传的图片方法
2019/07/26 Python
python图的深度优先和广度优先算法实例分析
2019/10/26 Python
django-xadmin根据当前登录用户动态设置表单字段默认值方式
2020/03/13 Python
浅谈keras中的batch_dot,dot方法和TensorFlow的matmul
2020/06/18 Python
Python 调用 ES、Solr、Phoenix的示例代码
2020/11/23 Python
用Python制作音乐海报
2021/01/26 Python
英国文具、办公用品和科技商店:Ryman
2018/09/27 全球购物
英国奢华护肤、美容和Spa品牌:Temple Spa
2019/11/02 全球购物
酒吧副总经理岗位职责
2013/12/10 职场文书
党员一帮一活动总结
2014/07/08 职场文书
小学家长学校培训材料
2014/08/24 职场文书
毕业酒会致辞
2015/07/29 职场文书
利用python实时刷新基金估值(摸鱼小工具)
2021/09/15 Python
Vue OpenLayer 为地图绘制风场效果
2022/04/24 Vue.js