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+MySQL的聊天室设计
Oct 09 PHP
一个高ai的分页函数和一个url函数
Oct 09 PHP
模仿OSO的论坛(四)
Oct 09 PHP
php生成随机数或者字符串的代码
Sep 05 PHP
一周让你学会PHP 不错的学习资料
Feb 06 PHP
thinkphp控制器调度使用示例
Feb 24 PHP
php提取身份证号码中的生日日期以及验证是否为成年人的函数
Sep 29 PHP
PHP命名空间和自动加载类
Apr 03 PHP
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
Dec 14 PHP
PHP实现链表的定义与反转功能示例
Jun 09 PHP
PHP命名空间定义与用法实例分析
Aug 14 PHP
php中加密解密DES类的简单使用方法示例
Mar 26 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
分享8个最佳的代码片段在线测试网站
2013/06/29 PHP
解决phpcms更换javascript的幻灯片代码调用图片问题
2014/12/26 PHP
PHP+MySQL修改记录的方法
2015/01/21 PHP
php结合安卓客户端实现查询交互实例
2015/05/05 PHP
Yii基于CActiveForm的Ajax数据验证用法示例
2016/07/14 PHP
PHP实现打包下载文件的方法示例
2017/10/07 PHP
获取当前网页document.url location.href区别总结
2008/05/10 Javascript
js防止表单重复提交实现代码
2012/09/05 Javascript
当滚动条滚动到页面底部自动加载增加内容的js代码
2014/05/13 Javascript
JavaScript实现将文本框的值插入指定位置的方法
2015/08/13 Javascript
基于javascript实现精确到毫秒的倒计时限时抢购
2016/04/17 Javascript
Nodejs下用submit提交表单提示cannot post错误的解决方法
2016/11/21 NodeJs
Angular的$http的ajax的请求操作(推荐)
2017/01/10 Javascript
微信小程序 两种滑动方式(横向滑动,竖向滑动)详细及实例代码
2017/01/13 Javascript
Javascript中的 “&” 和 “|” 详解
2017/02/02 Javascript
bootstrap suggest下拉框使用详解
2017/04/10 Javascript
详解Node项目部署到云服务器上
2017/07/12 Javascript
JS动画定时器知识总结
2018/03/23 Javascript
Vue CLI3.0中使用jQuery和Bootstrap的方法
2019/02/28 jQuery
Vue开发之watch监听数组、对象、变量操作分析
2019/04/25 Javascript
python合并文本文件示例
2014/02/07 Python
Python+django实现文件上传
2016/01/17 Python
python如何实现从视频中提取每秒图片
2020/10/22 Python
Python+Redis实现布隆过滤器
2019/12/08 Python
Python连接Mysql进行增删改查的示例代码
2020/08/03 Python
Python txt文件如何转换成字典
2020/11/03 Python
英国领先的豪华时尚家居网上商店:Amara
2019/08/12 全球购物
意大利和国际最佳时尚品牌:Drestige
2019/12/28 全球购物
培训班开班仪式主持词
2014/03/28 职场文书
党员三严三实心得体会
2014/10/13 职场文书
六年级语文下册教学计划
2015/01/22 职场文书
教师岗位职责
2015/02/03 职场文书
小学生心理健康活动总结
2015/05/08 职场文书
CocosCreator如何实现划过的位置显示纹理
2021/04/14 Javascript
JavaScript 事件捕获冒泡与捕获详情
2021/11/11 Javascript
详解Spring Security如何在权限中使用通配符
2022/06/28 Java/Android