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投票程序源码
Mar 11 PHP
Windows下XDebug 手工配置与使用说明
Jul 11 PHP
php设计模式 Mediator (中介者模式)
Jun 26 PHP
PHP中创建空文件的代码[file_put_contents vs touch]
Jan 20 PHP
深入PHP empty(),isset(),is_null()的实例测试详解
Jun 06 PHP
一个PHP二维数组排序的函数分享
Jan 17 PHP
ThinkPHP Mobile使用方法简明教程
Jun 18 PHP
ThinkPHP实现二级循环读取的方法
Nov 03 PHP
thinkPHP简单实现多个子查询语句的方法
Dec 05 PHP
PHP Laravel中的Trait使用方法
Jan 20 PHP
php中关于换行的实例写法
Sep 26 PHP
PhpStorm+xdebug+postman调试技巧分享
Sep 15 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 ob_start()控制浏览器cache、生成html实现代码
2010/02/16 PHP
php 魔术函数使用说明
2010/02/21 PHP
PHP命名空间(namespace)的动态访问及使用技巧
2014/08/18 PHP
PHP添加图片水印、压缩、剪切的封装类
2015/08/17 PHP
PHP-FPM和Nginx的通信机制详解
2019/02/01 PHP
PHP加MySQL消息队列深入理解
2021/02/27 PHP
JavaScript中的Math.atan2()方法使用详解
2015/06/15 Javascript
JS组件中bootstrap multiselect两大组件较量
2016/01/26 Javascript
浅谈jQuery添加的HTML,JS失效的问题
2016/10/05 Javascript
探讨AngularJs中ui.route的简单应用
2016/11/16 Javascript
使用Math.max,Math.min获取数组中的最值实例
2017/04/25 Javascript
利用原生js实现html5小游戏之打砖块(附源码)
2018/01/03 Javascript
简述pm2常用命令集合及配置文件说明
2019/05/30 Javascript
vue-cli脚手架的.babelrc文件用法说明
2020/09/11 Javascript
[11:27]《一刀刀一天》之DOTA全时刻20:TI4总奖金突破920W TS赛事分析
2014/06/18 DOTA
在Mac OS上使用mod_wsgi连接Python与Apache服务器
2015/12/24 Python
python numpy函数中的linspace创建等差数列详解
2017/10/13 Python
对python中Json与object转化的方法详解
2018/12/31 Python
Python3.6中Twisted模块安装的问题与解决
2019/04/15 Python
Django框架首页和登录页分离操作示例
2019/05/28 Python
python绘制双Y轴折线图以及单Y轴双变量柱状图的实例
2019/07/08 Python
python高斯分布概率密度函数的使用详解
2019/07/10 Python
对Tensorflow中tensorboard日志的生成与显示详解
2020/02/04 Python
python字符串,元组,列表,字典互转代码实例详解
2020/02/14 Python
win10下opencv-python特定版本手动安装与pip自动安装教程
2020/03/05 Python
用python按照图像灰度值统计并筛选图片的操作(PIL,shutil,os)
2020/06/04 Python
python 下载m3u8视频的示例代码
2020/11/11 Python
成教毕业生自我鉴定
2013/10/23 职场文书
高中生学习生活的自我评价
2013/11/27 职场文书
优秀的计算机专业求职信范文
2013/12/27 职场文书
计算机专业毕业生自荐信
2013/12/31 职场文书
国际贸易求职信
2014/07/05 职场文书
党的群众路线教育实践活动领导班子整改措施
2014/09/30 职场文书
美术教师个人总结
2015/02/06 职场文书
Python趣味挑战之用pygame实现简单的金币旋转效果
2021/05/31 Python
Python使用pandas导入csv文件内容的示例代码
2022/12/24 Python