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+MySQL5.0中文乱码解决方法
Nov 20 PHP
用来给图片加水印的PHP类
Apr 09 PHP
《PHP编程最快明白》第四讲:日期、表单接收、session、cookie
Nov 01 PHP
PHP遍历二维数组的代码
Apr 22 PHP
php XMLWriter类的简单示例代码(RSS输出)
Sep 30 PHP
PHP获取用户的浏览器与操作系统信息的代码
Sep 04 PHP
很让人受教的 提高php代码质量36计
Sep 05 PHP
PHP中实现生成静态文件的方法缓解服务器压力
Jan 07 PHP
PHP字符串中特殊符号的过滤方法介绍
Feb 18 PHP
PHP序列化的四种实现方法与横向对比
Nov 29 PHP
ThinkPHP3.1.2 使用cli命令行模式运行的方法
Apr 14 PHP
PHP获取php,mysql,apche的版本信息及更多服务器信息
Mar 09 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 empty,isset,is_null判断比较(差异与异同)
2010/10/19 PHP
解析php中array_merge与array+array的区别
2013/06/21 PHP
本地机apache配置基于域名的虚拟主机详解
2013/08/10 PHP
新手菜鸟必读:session与cookie的区别
2013/08/22 PHP
php命令行(cli)模式下报require 加载路径错误的解决方法
2015/11/23 PHP
PHP laravel中的多对多关系实例详解
2017/06/07 PHP
JavaScript的面向对象方法以及差别
2008/03/31 Javascript
通过继承IHttpHandle实现JS插件的组织与管理
2010/07/13 Javascript
js+css在交互上的应用
2010/07/18 Javascript
js 优化次数过多的循环 考虑到性能问题
2011/03/05 Javascript
js返回前一页刷新本页重载页面
2014/07/29 Javascript
基于JS实现无缝滚动思路及代码分享
2016/06/07 Javascript
使用BootStrap实现表格隔行变色及hover变色并在需要时出现滚动条
2017/01/04 Javascript
Vue项目中跨域问题解决方案
2018/06/05 Javascript
video.js 实现视频只能后退不能快进的思路详解
2018/08/09 Javascript
vue如何限制只能输入正负数及小数
2019/07/04 Javascript
深入解读VUE中的异步渲染的实现
2020/06/19 Javascript
小程序选项卡以及swiper套用(跨页面)
2020/06/19 Javascript
vue-cli3中配置alias和打包加hash值操作
2020/09/04 Javascript
python33 urllib2使用方法细节讲解
2013/12/03 Python
python中子类调用父类函数的方法示例
2017/08/18 Python
python中使用print输出中文的方法
2018/07/16 Python
详解python中list的使用
2019/03/15 Python
python字符串判断密码强弱
2020/03/18 Python
Python爬虫爬取有道实现翻译功能
2020/11/27 Python
漫威玩具服装及周边商品官方购物网站:Marvel Shop
2019/05/11 全球购物
Alexandre Birman美国官网:亚历山大·伯曼
2019/10/30 全球购物
化学系大学生自荐信范文
2014/03/01 职场文书
团日活动总结书格式
2014/05/08 职场文书
报效祖国演讲稿
2014/09/15 职场文书
2014年幼儿园园长工作总结
2014/12/17 职场文书
以权谋私检举信范文
2015/03/02 职场文书
redis连接被拒绝的解决方案
2021/04/12 Redis
Python超简单容易上手的画图工具库推荐
2021/05/10 Python
一文弄懂MySQL索引创建原则
2022/02/28 MySQL
Nginx 常用配置
2022/05/15 Servers