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去除数组中重复的元素并按键名排序函数
Aug 18 PHP
PHP print类函数使用总结
Jun 25 PHP
PHP 5.3 下载时 VC9、VC6、Thread Safe、Non Thread Safe的区别分析
Mar 28 PHP
PHP使用imagick读取PDF生成png缩略图的两种方法
Mar 20 PHP
destoon整合UCenter图文教程
Jun 21 PHP
PHP生成不重复标识符的方法
Nov 21 PHP
php实现将数组转换为XML的方法
Mar 09 PHP
php获取本周开始日期和结束日期的方法
Mar 09 PHP
CI(CodeIgniter)模型用法实例分析
Jan 20 PHP
php求数组全排列,元素所有组合的方法总结
Mar 14 PHP
php脚本守护进程原理与实现方法详解
Jul 20 PHP
PHP中“=>
Mar 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
PHP base64+gzinflate压缩编码和解码代码
2008/10/03 PHP
PHP+MySQL投票系统的设计和实现分享
2012/09/23 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
php实现图片缩略图的方法
2016/03/29 PHP
php操作redis数据库常见方法实例总结
2020/02/20 PHP
PHP实现基本留言板功能原理与步骤详解
2020/03/26 PHP
Nigma vs Liquid BO3 第一场2.13
2021/03/10 DOTA
FCK调用方法..
2006/12/21 Javascript
JavaScript Array Flatten 与递归使用介绍
2011/10/30 Javascript
jquery.ui.draggable中文文档(原文翻译)
2013/11/15 Javascript
js实现日期级联效果
2014/01/23 Javascript
jQuery操作select下拉框的text值和value值的方法
2014/05/31 Javascript
JS弹出可拖拽可关闭的div层完整实例
2015/02/13 Javascript
JavaScript中的Promise使用详解
2015/06/24 Javascript
jQuery EasyUI 入门必看
2016/06/03 Javascript
Angular.js初始化之ng-app的自动绑定与手动绑定详解
2017/07/31 Javascript
socket io与vue-cli的结合使用的示例代码
2018/11/01 Javascript
JS实现的碰撞检测与周期移动完整示例
2019/09/02 Javascript
node.js express捕获全局异常的三种方法实例分析
2019/12/27 Javascript
微信小程序如何实现精确的日期时间选择器
2020/01/21 Javascript
Python重新引入被覆盖的自带function
2014/07/16 Python
python中正则表达式的使用详解
2014/10/17 Python
python3连接MySQL数据库实例详解
2018/05/24 Python
pygame游戏之旅 添加游戏界面按键图形
2018/11/20 Python
Python PyInstaller库基本使用方法分析
2019/12/12 Python
深入浅析python变量加逗号,的含义
2020/02/22 Python
Python Selenium模块安装使用教程详解
2020/07/09 Python
园林设计师自荐信
2013/11/18 职场文书
大学生学年自我鉴定
2014/02/10 职场文书
婚礼证婚人演讲稿
2014/09/13 职场文书
大学生村官个人对照检查材料(群众路线)
2014/09/26 职场文书
计划生育汇报材料
2014/12/26 职场文书
2015年度销售个人工作总结
2015/03/31 职场文书
房地产工程部经理岗位职责
2015/04/09 职场文书
党员转正介绍人意见
2015/06/03 职场文书
《没有任何借口》读后感:完美的执行能力
2020/01/07 职场文书