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
第4章 数据处理-php字符串的处理-郑阿奇(续)
Jul 04 PHP
php 数组动态添加实现代码(最土团购系统的价格排序)
Dec 30 PHP
Linux Apache PHP Oracle 安装配置(具体操作步骤)
Jun 17 PHP
php可扩展的验证类实例(可对邮件、手机号、URL等验证)
Jul 09 PHP
thinkPHP中create方法与令牌验证实例浅析
Dec 08 PHP
简单的php+mysql聊天室实现方法(附源码)
Jan 05 PHP
thinkphp3.x中session方法的用法分析
May 20 PHP
PHP实现下载远程图片保存到本地的方法
Jun 19 PHP
php爬取天猫和淘宝商品数据
Feb 23 PHP
phpinfo的知识点总结
Oct 10 PHP
Laravel 登录后清空COOKIE的操作方法
Oct 14 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
Session保存到数据库的php类分享
2011/10/24 PHP
PHP判断文件是否存在、是否可读、目录是否存在的代码
2012/10/03 PHP
php实现简单洗牌算法
2013/06/18 PHP
ThinkPHP实现一键清除缓存方法
2014/06/26 PHP
总结的一些PHP开发中的tips(必看篇)
2017/03/24 PHP
Laravel中encrypt和decrypt的实现方法
2017/09/24 PHP
JavaScript方法和技巧大全
2006/12/27 Javascript
JScript 脚本实现文件下载 一般用于下载木马
2009/10/29 Javascript
AJAX的跨域与JSONP(为文章自动添加短址的功能)
2010/01/17 Javascript
jquery-easyui关闭tab自动切换到前一个tab
2010/07/29 Javascript
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
2011/03/30 Javascript
ASP.NET jQuery 实例7 通过jQuery来获取DropDownList的Text/Value属性值
2012/02/03 Javascript
JS获取鼠标坐标的实例方法
2013/07/18 Javascript
点击弹出层外区域关闭弹出层jquery特效示例
2013/08/25 Javascript
js冒泡、捕获事件及阻止冒泡方法详细总结
2014/05/08 Javascript
JavaScript判断浏览器对CSS3属性是否支持的多种方法
2016/11/13 Javascript
AngularJs 禁止模板缓存的方法
2017/11/28 Javascript
nodejs结合socket.io实现websocket通信功能的方法
2018/01/12 NodeJs
搭建vue开发环境
2018/07/19 Javascript
Vue项目引发的「过滤器」使用教程
2019/03/12 Javascript
vue实现表单未编辑或未保存离开弹窗提示功能
2020/04/08 Javascript
JS将指定的某个字符全部转换为其他字符实例代码
2020/10/13 Javascript
vue 动态添加的路由页面刷新时失效的原因及解决方案
2021/02/26 Vue.js
跟老齐学Python之编写类之三子类
2014/10/11 Python
python爬取足球直播吧五大联赛积分榜
2018/06/13 Python
python监控文件并且发送告警邮件
2018/06/21 Python
解决python字典对值(值为列表)赋值出现重复的问题
2019/01/20 Python
Python实现Mysql数据统计及numpy统计函数
2019/07/15 Python
用python给csv里的数据排序的具体代码
2020/07/17 Python
HTML5语义化元素你真的用对了吗
2019/08/22 HTML / CSS
英国最大的在线照明商店:Litecraft
2020/08/31 全球购物
大学生党课思想汇报
2013/12/29 职场文书
《槐乡五月》教学反思
2014/04/25 职场文书
企业宣传策划方案
2014/05/29 职场文书
法定代表人授权委托书范文
2014/08/02 职场文书
幼儿园2014年度工作总结
2014/11/10 职场文书