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 调试环境(IIS+PHP+MYSQL)
Jan 10 PHP
PHP向socket服务器收发数据的方法
Jan 24 PHP
Symfony2中被遗弃的getRequest()方法分析
Mar 17 PHP
CI框架源码解读之利用Hook.php文件完成功能扩展的方法
May 18 PHP
PHP用正则匹配form表单中所有元素的类型和属性值实例代码
Feb 28 PHP
PHP实现随机生成水印图片功能
Mar 22 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
Apr 18 PHP
PHP实现防盗链的方法分析
Jul 25 PHP
PHP Post获取不到非表单数据的问题解决办法
Feb 27 PHP
PHP实现用户登录的案例代码
May 10 PHP
php使用array_chunk函数将一个数组分割成多个数组
Dec 05 PHP
Laravel 5+ .env环境配置文件详解
Apr 06 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下载文件名中解决乱码的问题
2013/06/20 PHP
Symfony页面的基本创建实例详解
2015/01/26 PHP
php实现简单的MVC框架实例
2015/09/23 PHP
Laravel学习教程之IOC容器的介绍与用例
2017/08/15 PHP
php之header的不同用法总结(实例讲解)
2017/11/28 PHP
PHP生成腾讯云COS接口需要的请求签名
2018/05/20 PHP
JS中confirm,alert,prompt函数区别分析
2011/01/17 Javascript
js时间日期和毫秒的相互转换
2013/02/22 Javascript
判断复选框是否被选中的两种方法
2014/06/04 Javascript
javascript基础知识分享之类与函数化
2016/02/13 Javascript
JS hashMap实例详解
2016/05/26 Javascript
JavaScript实现移动端滑动选择日期功能
2016/06/21 Javascript
巧用Vue.js+Vuex制作专门收藏微信公众号的app
2016/11/03 Javascript
如何将 jQuery 从你的 Bootstrap 项目中移除(取而代之使用Vue.js)
2017/07/17 jQuery
Vue全局分页组件的实现代码
2018/08/10 Javascript
Egg.js 中 AJax 上传文件获取参数的方法
2018/10/10 Javascript
vue项目中监听手机物理返回键的实现
2020/01/18 Javascript
JavaScript实现点击切换功能
2021/01/27 Javascript
[49:56]VG vs Optic 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python中sys.argv参数用法实例分析
2015/05/20 Python
用Python进行简单图像识别(验证码)
2018/01/19 Python
Python UnboundLocalError和NameError错误根源案例解析
2018/10/31 Python
python远程连接MySQL数据库
2019/04/19 Python
Python生成一个迭代器的实操方法
2019/06/18 Python
python实现XML解析的方法解析
2019/11/16 Python
MxNet预训练模型到Pytorch模型的转换方式
2020/05/25 Python
pytorch中的weight-initilzation用法
2020/06/24 Python
StubHub墨西哥:购买和出售您的门票
2016/09/17 全球购物
营销与策划专业毕业生求职信
2013/11/01 职场文书
瘦西湖导游词
2015/02/03 职场文书
放假通知范文
2015/04/14 职场文书
2015年保洁员工作总结
2015/05/04 职场文书
Nginx配置https的实现
2021/11/27 Servers
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js
Python万能模板案例之matplotlib绘制甘特图
2022/04/13 Python
mysql sql常用语句大全
2022/06/21 MySQL