PHP编程:php session的锁和并发
《php session的锁和并发》要点: 本文分享PHP的session在使用过程中的锁和并发的问题,与之相关的现象有哀求阻塞、session数据丢失、session数据读不到. 我登录不了了
我们的系统 <input type="hidden" name="{{ security.getTokenKey() }}" value="{{ security.getToken() }}"/> <img src="/login/getCaptcha" id="img-captcha"/> 我首先对这两个组件进行查阅,发现他们都是将数据存于session: # phalcon/security.zep # Security::getToken() let session = <SessionInterface> dependencyInjector->getShared("session"); session->set(this->_tokenValueSessionID,token); $this->session->set('admin_get_captcha_action',$captcha); 然后我又查阅了我们session的实现,发现是将数据存储于redis的. 找啊找
我们可以看到: 1、这里存在两次哀求,一次是表单加载,一次是生成验证码的. php的session数据的存取 这个问题的答案可能和一些朋友想的不一样,一个哀求里面,PHP只会读取一次存储器,在session_start的时候,然后也只会写入一次存储器,在哀求结束的时候,或调用session_write_close的时候,将数据刷回存储器,关闭session. 那么问题来了: 1、如果一个会话,同时出现两个读写session哀求,没有保证获取1-写入1-获取2-写入2,同时没有cas版本管理机制的情况下,这些并发哀求就会彼此读取不到对方的写入,最后写入的会把前面哀求写入的session覆盖掉. 其实锁是不大适合,有弊端的. php的session,默认是用文件存储的,在打开session的时候,会对文件加独占锁,这样,其它哀求就无法获取锁了,只能等待直到前面的锁解了. 这样保证了 读取-写入,读取-写入的顺序. 其它存储器,例如mysql,可以借助select for update进行行锁.redis可以通过一个自增键,返回1的获取到锁等来实现. 这个实现的话,对数据流来说很理想,但是,对于目前这种页面大量应用ajax的情况,所有哀求排队处理,将大大加大页面展现的耗时,甚至出现哀求超时等不可用故障. 没有解决的解决 # 立刻回写session,避免session覆盖 $eventManager = $this->view->getEventsManager(); if (!$eventManager) { $eventManager = new Manager(); $this->view->setEventsManager($eventManager); } $eventManager->attach("view:afterRender",function(){ session_write_close(); }); return $this->view; if($login) { # 立刻回写session,避免session读取不到 $eventManager = $this->dispatcher->getEventsManager(); if (!$eventManager) { $eventManager = new Manager(); $this->dispatcher->setEventsManager($eventManager); } $eventManager->attach('dispatch:afterDispatchLoop',function(){ session_write_close(); }); return $this->response->setHeader('Location','/'); } 以上就是关于php session的锁和并发,希望对大家的学习有所赞助. 编程之家培训学院每天发布《php session的锁和并发》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |