PHP通过加锁实现并发情况下抢码功能


Posted in PHP onAugust 10, 2016

需求:抢码功能

要求:

1、特定时间段才开放抢码;

2、每个时间段放开的码是有限的;

3、每个码不允许重复;

实现:

1、在不考虑并发的情况下实现:

function get_code($len){
$CHAR_ARR = array('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','X','Y','Z','W','S','R','T');
$CHAR_ARR_LEN = count($CHAR_ARR) - 1;
$code = '';
while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; }
return $code;
}
$pdo = new PDO('mysql:host=localhost;dbname=ci_test','root','root');
//查询当前时间已发放验证码数量
$code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test");
$code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC);
$code_num = $code_num_arr['sum'];
if($code_num < 1){<br> sleep(2); //暂停2秒
$code = get_code(6);
var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES ('$code',".time().")") );
}

上述代码默认满足当前是开放时间,和码是不重复的; 

     在不考虑并发情况下流程:

1)选查询当前数据库发放的验证码数量;

2)如果还有名额,则生成验证码,插入到数据库,返回验证码到客户端;

3)如果已满;则返回提示,已无名额;

2、并发情况下实现:

那么看下上面代码在并发情况下得到的结果:

测试并发,可以使用apache benchmark来测试,apache benchmark是APACHE旗下的HTTP SERVER的性能评测工具,通过cmd进入到apche的bin目录下,通过ab命令调用,如:ab -c 并发数量 -n 总访问量 url

cb -c 100 -n 100 http://localhost/php_mulit.php

这样就是100个用户同事去抢1个名额,在查询的时候,每个用户都查询到还有一个名额,则会去生成验证码,插入数据库,返回验证码;这样就造成了验证码发多了。事实上,运行完该命令,数据库多了13条记录,而不是一条。

怎么避免这情况发生呢? 

     可以通过加排他锁来锁定判断到插入这个过程,保证这个判断流程任意一时间只有一个进程在运行。实现如下:

//生成码
function get_code($len){
$CHAR_ARR = array('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','X','Y','Z','W','S','R','T');
$CHAR_ARR_LEN = count($CHAR_ARR) - 1;
$code = '';
while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; }
return $code;
}
$pdo = new PDO('mysql:host=localhost;dbname=ci_test','root','root');
$fp = fopen('lock.txt','r');
//通过排他锁 锁定该过程
if(flock($fp,LOCK_EX)){
//查询当前时间已发放验证码数量
$code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test");
$code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC);
$code_num = $code_num_arr['sum'];
if($code_num < 1){
sleep(2);
$code = get_code(6);
var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES ('$code',".time().")") );
}
flock($fp,LOCK_UN);
fclose($fp);
}

通过flock函数来锁定该过程。

更多flock信息可以参考php手册:http://php.net/manual/zh/function.flock.php

再次运行

cb -c 100 -n 100 http://localhost/php_mulit.php

数据库只增加了一条记录,保证了并发情况下数据的正确。

以上所述是小编给大家介绍的PHP通过加锁实现并发情况下抢码功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
PHP图片处理类 phpThumb参数用法介绍
Mar 11 PHP
CI框架装载器Loader.php源码分析
Nov 04 PHP
php实现比较全的数据库操作类
Jun 18 PHP
PHP结合jQuery实现找回密码
Jul 22 PHP
java模拟PHP的pack和unpack类
Apr 13 PHP
Yii2使用自带的UploadedFile实现的文件上传
Jun 20 PHP
PHP入门教程之操作符与控制结构流程详解
Sep 09 PHP
PHP实现的解汉诺塔问题算法示例
Aug 06 PHP
PHP中创建和编辑Excel表格的方法
Sep 13 PHP
laravel-admin 后台表格筛选设置默认的查询日期方法
Oct 03 PHP
laravel框架如何设置公共头和公共尾
Oct 22 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
Mar 24 PHP
PHP身份证校验码计算方法
Aug 10 #PHP
PHP5.4起内置web服务器使用方法
Aug 09 #PHP
PHP Filter过滤器全面解析
Aug 09 #PHP
学习PHP Cookie处理函数
Aug 09 #PHP
利用PHP命令行模式采集股票趋势信息
Aug 09 #PHP
PHP怎样用正则抓取页面中的网址
Aug 09 #PHP
php阳历转农历优化版
Aug 08 #PHP
You might like
php数据库配置文件一般做法分享
2012/07/07 PHP
初识ThinkPHP控制器
2016/04/07 PHP
JQuery 学习笔记 选择器之二
2009/07/23 Javascript
基于jquery的固定表头和列头的代码
2012/05/03 Javascript
JS实现悬浮移动窗口(悬浮广告)的特效
2013/03/12 Javascript
javascript实例分享---具有立体效果的图片特效
2014/06/08 Javascript
node.js中的fs.existsSync方法使用说明
2014/12/17 Javascript
Bootstrap源码解读标签、徽章、缩略图和警示框(8)
2016/12/26 Javascript
详解nodejs微信公众号开发——6.自定义菜单
2017/04/13 NodeJs
在Vue中使用highCharts绘制3d饼图的方法
2018/02/08 Javascript
vue-cli 脚手架基于Nightwatch的端到端测试环境的过程
2018/09/30 Javascript
vue ssr 实现方式(学习笔记)
2019/01/18 Javascript
JS/jQuery实现简单的开关灯效果【案例】
2019/02/19 jQuery
多个vue子路由文件自动化合并的方法
2019/09/03 Javascript
基于vue实现探探滑动组件功能
2020/05/29 Javascript
vue项目,代码提交至码云,iconfont的用法说明
2020/07/30 Javascript
JavaScript实现动态生成表格
2020/08/02 Javascript
python里对list中的整数求平均并排序
2014/09/12 Python
python 时间戳与格式化时间的转化实现代码
2016/03/23 Python
Django1.7+python 2.78+pycharm配置mysql数据库
2016/10/09 Python
python实现一行输入多个值和一行输出多个值的例子
2019/07/16 Python
Python中如何添加自定义模块
2020/06/09 Python
Python+OpenCV检测灯光亮点的实现方法
2020/11/02 Python
python中lower函数实现方法及用法讲解
2020/12/23 Python
Python字符串对齐、删除字符串不需要的内容以及格式化打印字符
2021/01/23 Python
欧舒丹俄罗斯官方网站:L’OCCITANE俄罗斯
2019/11/22 全球购物
一组SQL面试题
2016/02/15 面试题
搞笑获奖感言
2014/01/30 职场文书
音乐教学反思
2014/02/02 职场文书
中学教师教育感言
2014/02/21 职场文书
党员查摆四风问题思想汇报
2014/10/25 职场文书
2014年法务工作总结
2014/12/11 职场文书
研究生论文答辩开场白
2015/05/27 职场文书
三八节祝酒词
2015/08/11 职场文书
新学期家长寄语2016
2015/12/03 职场文书
Python上下文管理器Content Manager
2021/06/26 Python