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写的serv-u的web申请账号的程序
Oct 09 PHP
php checkdate、getdate等日期时间函数操作详解
Mar 11 PHP
php程序效率优化的一些策略小结
Jul 17 PHP
php excel类 phpExcel使用方法介绍
Aug 21 PHP
关于php curl获取301或302转向的网址问题的解决方法
Jun 02 PHP
Smarty变量调节器失效的解决办法
Aug 20 PHP
php中常见的sql攻击正则表达式汇总
Nov 06 PHP
PHP通过串口实现发送短信
Jul 08 PHP
php实现xml与json之间的相互转换功能实例
Jul 07 PHP
Ajax实现对静态页面的文章访问统计功能示例
Oct 10 PHP
php计算给定日期所在周的开始日期和结束日期示例
Feb 06 PHP
PHP实现Session入库/存入redis的方法
May 04 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常用特殊运算符号和函数总结(php新手入门必看)
2013/02/02 PHP
PHP引用符&amp;的用法详细解析
2013/08/22 PHP
JSON用法之将PHP数组转JS数组,JS如何接收PHP数组
2015/10/08 PHP
php设计模式之享元模式分析【星际争霸游戏案例】
2020/03/23 PHP
JQuery UI的拖拽功能实现方法小结
2012/03/14 Javascript
15条JavaScript最佳实践小结
2013/08/09 Javascript
javaScript实现浮点数转十六进制字符
2013/10/29 Javascript
javascript实现全局匹配并替换的方法
2015/04/27 Javascript
javascript小数精度丢失的完美解决方法
2016/05/31 Javascript
jQuery使用正则表达式限制文本框只能输入数字
2016/06/18 Javascript
Javascript动画效果(2)
2016/10/11 Javascript
浅析node.js的模块加载机制
2018/05/25 Javascript
对angularJs中2种自定义服务的实例讲解
2018/09/30 Javascript
详解微信小程序开发用户授权登陆
2019/04/24 Javascript
vue webpack重写cookie路径的方法
2019/07/10 Javascript
vue中created和mounted的区别浅析
2019/08/13 Javascript
VUE 单页面使用 echart 窗口变化时的用法
2020/07/30 Javascript
Python机器学习之K-Means聚类实现详解
2018/02/22 Python
Django Rest framework之认证的实现代码
2018/12/17 Python
python3文件复制、延迟文件复制任务的实现方法
2019/09/02 Python
Django中的FBV和CBV用法详解
2019/09/15 Python
django数据模型on_delete, db_constraint的使用详解
2019/12/24 Python
Python列表如何更新值
2020/05/27 Python
Python新手学习装饰器
2020/06/04 Python
英国户外服装、鞋类和设备的领先零售商:Millets
2020/10/12 全球购物
大学生入党思想汇报
2014/01/01 职场文书
生物科学专业职业规划书范文
2014/02/11 职场文书
优秀护士获奖感言
2014/02/20 职场文书
《花木兰》教学反思
2014/04/09 职场文书
消防安全宣传标语
2014/06/07 职场文书
幼儿园感恩节活动方案2014
2014/10/11 职场文书
工程资料员岗位职责
2015/04/13 职场文书
2015年暑期社会实践总结
2015/07/13 职场文书
数学复习课教学反思
2016/02/18 职场文书
python编程简单几行代码实现视频转换Gif示例
2021/10/05 Python
ubuntu下常用apt命令介绍
2022/06/05 Servers