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 相关文章推荐
用cookies来跟踪识别用户
Oct 09 PHP
require(),include(),require_once()和include_once()区别
Mar 27 PHP
php session应用实例 登录验证
Mar 16 PHP
深入apache host的配置详解
Jun 09 PHP
深入php中var_dump方法的使用详解
Jun 24 PHP
使用PHP获取汉字的拼音(全部与首字母)
Jun 27 PHP
php实现MD5加密16位(不要默认的32位)
Aug 12 PHP
PHP中判断变量为空的几种方法分享
Aug 26 PHP
PHP中使用Imagick实现各种图片效果实例
Jan 21 PHP
Zend Framework基本页面布局分析
Mar 19 PHP
php中的explode()函数实例介绍
Jan 18 PHP
php中错误处理操作实例分析
Aug 23 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入门学习知识点七 PHP函数的基本应用
2011/07/14 PHP
解析crontab php自动运行的方法
2013/06/24 PHP
PHP实现读取一个1G的文件大小
2013/08/24 PHP
PHP函数extension_loaded()用法实例
2015/01/19 PHP
实例介绍PHP中zip_open()函数用法
2019/02/15 PHP
JavaScript 学习笔记(十四) 正则表达式
2010/01/22 Javascript
js下通过getList函数实现分页效果的代码
2010/09/17 Javascript
angular.element方法汇总
2015/01/07 Javascript
JavaScript中reduce()方法的使用详解
2015/06/09 Javascript
浅谈Javascript线程及定时机制
2015/07/02 Javascript
jQuery原生的动画效果
2015/07/10 Javascript
chrome浏览器如何断点调试异步加载的JS
2016/09/05 Javascript
使用JS实现气泡跟随鼠标移动的动画效果
2017/09/16 Javascript
vue项目动态设置页面title及是否缓存页面的问题
2018/11/08 Javascript
js时间戳转yyyy-MM-dd HH-mm-ss工具类详解
2019/04/30 Javascript
Vue实现回到顶部和底部动画效果
2019/07/31 Javascript
不依任何赖第三方,单纯用vue实现Tree 树形控件的案例
2020/09/21 Javascript
Python实现全角半角字符互转的方法
2016/11/28 Python
不要用强制方法杀掉python线程
2017/02/26 Python
Pytorch evaluation每次运行结果不同的解决
2020/01/02 Python
PyQt5中多线程模块QThread使用方法的实现
2020/01/31 Python
pytorch使用tensorboardX进行loss可视化实例
2020/02/24 Python
玩转CSS3色彩
2010/01/16 HTML / CSS
纯CSS3发光分享按钮的实现教程
2014/09/06 HTML / CSS
MVMT手表官方网站:时尚又实惠的高品质手表
2016/12/04 全球购物
亚历山大·王官网:Alexander Wang
2017/06/23 全球购物
荟萃全球保健品:维他购
2018/05/09 全球购物
美国瑜伽服装和装备购物网站:Mukha Yoga
2019/02/22 全球购物
采购部经理岗位职责
2014/02/10 职场文书
竞聘书模板
2014/03/31 职场文书
小学班主任培训方案
2014/06/04 职场文书
初三语文教学计划
2015/01/22 职场文书
医院见习总结
2015/06/24 职场文书
Python中的min及返回最小值索引的操作
2021/05/10 Python
SpringBoot详解整合Redis缓存方法
2022/07/15 Java/Android
html,css,javascript是怎样变成页面的
2023/05/07 HTML / CSS