并发大家都知道是什么情况,这里说的是并发多个请求抢占同一个资源,直接上实例吧

请求:index.php?mod=a&action=b&taskid=6
处理:

$key = "a_b::".$uid.'_'.$taskid;
$v = $redis->get($key);
if($v == 1){$redis->setex($key,10,1);//处理逻辑省略
}

逻辑看来还可以,结果发现数据库中写入了两个同样的请求结果,我看了记录的时间戳,天!居然是同一秒.
我用microtime(true) log一下两个请求的时间差居然相差了0.0001s,就是说$redis->setex($key,10,1);还没执行成功 第二个请求已经get到跟第一个请求一样的结果。这不就是传说中的并发抢占资源。这中情况 听过很多,在开发过程中也没刻意去模拟实验过
第一反应就是要给处理过程加事务(数据库是mysql innoDB),加事务的结果就是 第一个请求成功了 第二个请求会执行到后面捡查发现重了会回滚
其实mysql事务在保证数据一致性上是很ok的,但是通过回滚来保证唯一资源独占代价太大,做过mysql事务测试测同学都知道,事务中的insert是已经插进去了,回滚之后才删掉的。
还有一个选择就是php中的文件独占锁,那就是说这情况下我要新建 用户数 * 任务数的文件来实现每个请求资源的独占,如果独占资源较少的话可选的解决办法:

    /*** 加锁*/public function file_lock($filename){$fp_key = sha1($filename);$this->fps[$fp_key] = fopen($filename, 'w+');if($this->fps[$fp_key]){return flock($this->fps[$fp_key], LOCK_EX|LOCK_NB);}return false;}/*** 解锁*/public function file_unlock($filename){$fp_key = sha1($filename);if($this->fps[$fp_key] ){flock($this->fps[$fp_key] , LOCK_UN);fclose($this->fps[$fp_key] );}}

发现$redis->setnx()可以提供原子操作的状态:相同的key执行setnx之后没过期或者没del,再执行会返回false。这就让两个以上的并发请求得到控制必须成功获取锁才能继续。
下面的是我实现的代码:

/***  加锁*/public function task_lock($taskid){$expire = 2;$lock_key ='task_get_reward_'.$this->uid.'_'.$taskid;$lock = $this->redis->setNX($lock_key , time());//设当前时间if($lock){$this->redis->expire($lock_key,  $expire); //如果没执行完 2s锁失效}if(!$lock){//如果获取锁失败 检查时间$time = $this->redis->get($lock_key);if(time() - $time  >=  $expire){//添加时间戳判断为了避免expire执行失败导致死锁 当然可以用redis自带的事务来保证$this->redis->rm($lock_key);}$lock =  $this->redis->setNX($lock_key , time());if($lock){$this->redis->expire($lock_key,  $expire); //如果没执行完 2s锁失效}}return $lock;}/***  解锁*/public function task_unlock($taskid){$this->set_redis();$lock_key = 'task_get_reward_'.$this->uid.'_'.$taskid;$this->redis->rm($lock_key);}

说明下setNX 和expire 这两个操作其实可以用redis事务来保证一致性

php 并发控制中的独占锁相关推荐

  1. php独占登录,php并发控制中的独占锁

    1.并发问题 并发大家都知道是什么情况,这里说的是并发多个请求抢占同一个资源,直接上实例吧 请求:index.php?mod=a&action=b&taskid=6 处理: $key ...

  2. Java开发技巧——并发控制中的乐观锁与悲观锁

    1.为什么需要锁? 在多用户环境中,在同一时间可能会有多个用户新相同的记录,这会产生冲突.这就是的并发性问题. 2.典型的冲突类型: (1)丢失新:一个事务的新覆盖了其它事务的新结果,就是所谓的新丢失 ...

  3. 并发控制中的乐观锁与悲观锁

    为什么需要锁(并发控制)? 在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突.这就是著名的并发性问题. 典型的冲突有: (1)丢失更新:一个事务的更新覆盖了其它事务的更新结果,就 ...

  4. 聊聊数据库中的那些锁

    背景 数据库中有一张叫后宫佳丽的表,每天都有几百万新的小姐姐插到表中,光阴荏苒,夜以继日,日久生情,时间长了,表中就有了几十亿的小姐姐数据,看到几十亿的小姐姐,每到晚上,我可愁死了,这么多小姐姐,我翻 ...

  5. 数据库并发控制,选择乐观锁还是悲观锁?

    出处:http://www.cnblogs.com/chenlulouis/  今天,在这里,我们将讨论的是在实际生产过程中,对于并发控制你是选择乐观锁还是悲观锁.这两种锁各自的应用环境应该怎样选择? ...

  6. java 共享锁 独占锁_java中的公平锁、非公平锁、可重入锁、递归锁、自旋锁、独占锁和共享锁...

    一.公平锁与非公平锁 1.1 概述 公平锁:是指多个线程按照申请锁的顺序来获取锁. 非公平锁:是指在多线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取到锁,在高并发的情 ...

  7. mysql 的独占锁和排它锁_数据库中的共享锁与排他锁

    摘要: 能修改数据.为什么要加锁很多人都知道,锁是用来解决并发问题的,那么什么是并发问题呢?并发情况下,不加锁会有什么问题呢?拿生活中的洗手间举例子,每个洗手间都会有一个门,并且是可以上锁的,当我们进 ...

  8. Java中的锁机制 -- 乐观锁、悲观锁、自旋锁、可重入锁、读写锁、公平锁、非公平锁、共享锁、独占锁、重量级锁、轻量级锁、偏向锁、分段锁、互斥锁、同步锁、死锁、锁粗化、锁消除

    文章目录 1. Java中的锁机制 1.1 乐观锁 1.2 悲观锁 1.3 自旋锁 1.4 可重入锁(递归锁) 1.5 读写锁 1.6 公平锁 1.7 非公平锁 1.8 共享锁 1.9 独占锁 1.1 ...

  9. 把MySQL中的各种锁及其原理都画出来

    疫情期间在家工作时,同事使用了 insert into on duplicate key update 语句进行插入去重,但是在测试过程中发生了死锁现象: ERROR 1213 (40001): De ...

最新文章

  1. Mac 安装多个版本jdk
  2. matlab 函数 向量参数,Scipy integrate(quad,quadration,nquad)不能集成向量参数化函数?等效函数(MATLAB works)...
  3. Dockerfile中的保留字指令讲解
  4. 蓝牙打印和网口打印的实现
  5. [论文阅读] Annotation-Efficient Cell Counting
  6. ASP.NET分类信息站全站制作视频教程5(AJAX+SQLITE+生成静态HTML)
  7. AR引擎vuforia源码分析、中文注释(2)用手势控制来与模型简单交互
  8. Ubuntu默认Python版本选择
  9. 俄罗斯方块、纯前端实现俄罗斯方块、俄罗斯方块代码
  10. 非常好用的jdk帮助文档jdk1.8中文谷歌翻译
  11. pc企业微信hook接口,企业微信营销软件,企业微信群发
  12. NB-IOT (2)---移远BC26模块模组快速入门
  13. 5G 商用第三年:无人驾驶的“上山”与“下海”
  14. cad.net cad启动慢? cad2008启动慢? cad启动延迟? cad卡住? cad98%卡? 默认打印机!!
  15. 2016年全球超级计算机榜首是,中国神威·太湖之光荣登全球超级计算机500强榜首...
  16. 一文读懂什么是EPP、EDR、CWPP、HIDS及业内主流产品
  17. 金融借贷平台大数据风控解决方案
  18. wps在线预览接口_文档在线预览的实现
  19. Kubernetes kata-container 介绍
  20. Kubectl debug 调试容器

热门文章

  1. C语言小于n的素数,关于求N以内素数的一点小问题(N小于一亿)
  2. linux 版本信息 64位,Centos查看版本信息
  3. 【Oracle】DG中物理备库、快照备库的相互转换
  4. 编译Android源码致命错误解决方案
  5. nginx之206异常
  6. 本地Apache服务器访问时502 Server dropped connection 错误解决方法
  7. [PVE]解决 ProXmoX VE升级 apt-get update 报错的问题
  8. 如何取消选中单选按钮?
  9. ubuntu18.04下 c++安装opencv-3.4.6,c++安装opencv-3.4.9,clion配置opencv-3.4.6与 python安装 opencv-3.4.6
  10. 怎样通过ip查看linux密码,怎么根据linux根据ip地址查主机名