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 相关文章推荐
PHP4(windows版本)中的COM函数
Oct 09 PHP
PHP5 面向对象(学习记录)
Dec 02 PHP
《PHP编程最快明白》第六讲:Mysql数据库操作
Nov 01 PHP
Fine Uploader文件上传组件应用介绍
Jan 06 PHP
如何用PHP实现插入排序?
Apr 10 PHP
php上传文件中文文件名乱码的解决方法
Nov 01 PHP
摘自织梦CMS的HTTP文件下载类
Aug 08 PHP
XHProf报告字段含义的解析
May 17 PHP
PHP CURL使用详解
Mar 21 PHP
Thinkphp5.0 框架的请求方式与响应方式分析
Oct 14 PHP
thinkphp5实现微信扫码支付
Dec 23 PHP
php 原生分页
Apr 01 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
PDO::setAttribute讲解
2019/01/29 PHP
JavaScript的eval JSON object问题
2009/11/15 Javascript
jquery表单验证使用插件formValidator
2012/11/10 Javascript
jquery获取特定name所有选中的checkbox,支持IE9标准模式
2013/03/18 Javascript
jQuery基本过滤选择器使用介绍
2013/04/18 Javascript
JS 操作Array数组的方法及属性实例解析
2014/01/08 Javascript
jquery map方法使用示例
2014/04/23 Javascript
node.js中的favicon.ico请求问题处理
2014/12/15 Javascript
jQuery实现可展开合拢的手风琴面板菜单
2015/09/15 Javascript
JavaScript基础——使用Canvas绘图
2016/11/02 Javascript
EasyUI学习之DataGird分页显示数据
2016/12/29 Javascript
Bootstrap响应式导航由768px变成992px的实现代码
2017/06/15 Javascript
AngularJS 实现点击按钮获取验证码功能实例代码
2017/07/13 Javascript
Vue DevTools调试工具的使用
2017/12/05 Javascript
解决一个微信号同时支持多个环境网页授权问题
2019/08/07 Javascript
AntV F2和vue-cli构建移动端可视化视图过程详解
2019/10/08 Javascript
ant design vue中表格指定格式渲染方式
2020/10/28 Javascript
python备份文件以及mysql数据库的脚本代码
2013/06/10 Python
Python 错误和异常小结
2013/10/09 Python
Django静态资源URL STATIC_ROOT的配置方法
2014/11/08 Python
基于python中staticmethod和classmethod的区别(详解)
2017/10/24 Python
Python3内置模块pprint让打印比print更美观详解
2019/06/02 Python
Python中itertools的用法详解
2020/02/07 Python
解决python3插入mysql时内容带有引号的问题
2020/03/02 Python
python实现将中文日期转换为数字日期
2020/07/14 Python
逼真的HTML5树叶飘落动画
2016/03/01 HTML / CSS
高二物理教学反思
2014/02/08 职场文书
人力资源总监工作说明
2014/03/03 职场文书
销售人员求职信
2014/07/22 职场文书
焦裕禄精神心得体会
2014/09/02 职场文书
勿忘国耻9.18演讲稿(经典篇)
2014/09/14 职场文书
小学生校园广播稿
2014/09/28 职场文书
党员群众路线教育实践活动学习笔记
2014/11/05 职场文书
教你使用一行Python代码玩遍童年的小游戏
2021/08/23 Python
MySQL面试题讲解之如何设置Hash索引
2021/11/01 MySQL
JS前端可视化canvas动画原理及其推导实现
2022/08/05 Javascript