PHP的Session阻塞机制带来的单页面多ajax请求阻塞的解决
遇到一个有意思的问题:
在一个页面中,有两个不同的ajax请求,分别在两个函数中调用去请求,前一个ajax是一个需要超长时间执行的请求。后一个ajax是每隔2秒执行一次,负责读取前一个ajax执行的日志,并把读到的日志内容显示在当前页面的某一个div中。
问题很简单,但意外发生了。
前面的ajax请求开始执行后,日志内容也正常不断的生成。但后一个ajax定时去取日志却总也取不到,看到的现象是没反应。直到第一个ajax请求执行结 束,日志内容才一下子全部被读出,显示在div中,这显示不是想要的结果,想要的是在第一个ajax请求在执行过程中,就拿到执行日志并显示。
这 个奇怪了,怎么会取不到呢?注释掉第二个方法中的Ajax的请求代码,直接写死一句话,然后刷新后再执行前一个Ajax请求后,观察到第二个注释后 ajax请求后的函数正常工作,写死的的那句话也每2秒一次写入到结果div中。说明定时执行是正常工作的,但如果有Ajax请求就无法正常工作,那问题 到底出在哪里?
打开firebug,观察发现,当前一个ajax请求在进行时,后面的定时请求也在不断生成,但是一直是等待状态,非要等到前一个ajax请求执行结束,后面的ajax请求才能成功请求!说明前一个ajax执行导致了阻塞影响到了后面的所有请求!
查阅相关PHP阻塞的资料,发现有人遇到过类似问题,是由于php的session阻塞机制导致的!
只 要执行了session_start方法,就会创建session,我们知道,每个客户端在请求的时候,session是存储在文件中的。而且同一个客户 端只会共用一个相同的session。一个请求占有了Session后,实际上是以读写方式打开了session文件。为了防止冲突,后面的请求只能等 待。
在本例中,第一个长时间执行的ajax占有了session后,加了读写锁,后面的请求无法获得相同session文件的读写锁,故只能等待前一个请求释放session。
搞清楚了问题原因,解决就好解决了。
1)如果可以不用session_start,则不使用。有时候执行这个句往往是出于习惯或原来代码就这么的,为什么不知道,呵呵。
2)无法避免使用session_start的,那也没关系,写完session内容后,及时关闭。关闭方法很简单。 session_write_close();本例是第二种情况,这两个ajax请求都不需要读写session,于是执行在最前面加上了session_write_close();后问题解决。