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 19 PHP
PHP应用JSON技巧讲解
Feb 03 PHP
php写的AES加密解密类分享
Jun 20 PHP
php内存缓存实现方法
Jan 24 PHP
分享一则PHP定义函数代码
Feb 26 PHP
浅谈php+phpStorm+xdebug配置方法
Sep 17 PHP
PHP程序员的技术成长规划
Mar 25 PHP
php封装db类连接sqlite3数据库的方法实例
Dec 19 PHP
PHP设计模式之PHP迭代器模式讲解
Mar 22 PHP
php使用mysqli和pdo扩展,测试对比mysql数据库的执行效率完整示例
May 09 PHP
Laravel 类和接口注入相关的代码
Oct 15 PHP
tp5 实现列表数据根据状态排序
Oct 18 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
德劲1104的电路分析与改良
2021/03/01 无线电
Zend引擎的发展 [15]
2006/10/09 PHP
PHP获取163、gmail、126等邮箱联系人地址【已测试2009.10.10】
2009/10/11 PHP
xml在joomla表单中的应用详解分享
2012/07/19 PHP
PHP制作图形验证码代码分享
2014/10/23 PHP
php基于 swoole 实现的异步处理任务功能示例
2019/08/13 PHP
奇妙的js
2007/09/24 Javascript
jQuery 性能优化指南(2)
2009/05/21 Javascript
JavaScript 高级语法介绍
2009/06/15 Javascript
在jquery boxy中添加百度地图坐标拾取注意流程
2014/04/03 Javascript
JQuery教学之性能优化
2014/05/14 Javascript
JavaScript中原型和原型链详解
2015/02/11 Javascript
jquery实现的Banner广告收缩效果代码
2015/09/02 Javascript
JavaScript中的splice方法用法详解
2016/07/20 Javascript
基于JavaScript实现全选、不选和反选效果
2017/02/15 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
vue-lazyload图片延迟加载插件的实例讲解
2018/02/09 Javascript
vue中倒计时组件的实例代码
2018/07/06 Javascript
python 合并文件的具体实例
2013/08/08 Python
跟老齐学Python之关于类的初步认识
2014/10/11 Python
python使用Pycharm创建一个Django项目
2018/03/05 Python
django 删除数据库表后重新同步的方法
2018/05/27 Python
利用pyinstaller打包exe文件的基本教程
2019/05/02 Python
python pyinstaller 加载ui路径方法
2019/06/10 Python
python实现异常信息堆栈输出到日志文件
2019/12/26 Python
python 遗传算法求函数极值的实现代码
2020/02/11 Python
Python正则表达式学习小例子
2020/03/03 Python
解决django中form表单设置action后无法回到原页面的问题
2020/03/13 Python
keras分类之二分类实例(Cat and dog)
2020/07/09 Python
玩具反斗城美国官网:Toys"R"Us
2016/09/17 全球购物
关于递归的一道.NET面试题
2013/05/12 面试题
教师找工作推荐信
2013/11/23 职场文书
浪费资源的建议书
2014/03/12 职场文书
建筑专业毕业生自荐信
2014/05/25 职场文书
乡镇精神文明建设汇报材料
2014/08/15 职场文书
领导个人查摆剖析材料
2014/10/29 职场文书