session_write_close在查询之前调用它时会做什么?

时间:2014-06-17 12:00:42

标签: php sql

我想知道session_write_close()做了什么。我发现手册有点模糊。 我有一些非常大的SELECT查询。在SELECTsession_write_close()次查询之前,我正在调用session_start(),在查询之后我再次呼叫SELECT

你可能想知道为什么我这样做,如果我没有并且用户正在执行其中一个session_write_close()查询并中止它们(例如试图打开另一个页面),则用户可以&#39 ; t打开新页面(或必须等待很长时间)。我认为因为脚本正在等待大型查询完成。

所以我的问题:
session_write_close()在查询之前调用它时究竟做了什么?

为什么用户在打开新页面时,在中止查询时不得不等待(在查询之前使用{{1}})?


提前致谢

2 个答案:

答案 0 :(得分:5)

PHP的默认会话存储只是硬盘上的一个文件。即,$_SESSION的内容只是简单地转储到磁盘上的文件中。当您致电session_start时,将读取该文件并填充$_SESSION,当脚本结束时,$_SESSION将被写回磁盘。

这里很容易进入经典的比赛状态。如果两个请求并行进入,并且从文件中读取了两个独立的脚本,那么稍后两个脚本会回写到文件中...哪一个获胜?该文件的内容是什么,可能是否有一些数据被覆盖?

解决方案是文件锁定。 PHP获取会话文件的锁定,阻止其他任何人读取或写入它,直到锁定被解除。如果两个并行脚本同时尝试获取锁,则其中一个必须等​​到另一个完成。这就是你所看到的。

session_write_close显式将$_SESSION内容写入磁盘并放弃锁定。

答案 1 :(得分:2)

我希望下面的图表有助于理解发生了什么;我们正在讨论同一用户的会话(即同一会话ID):

script a             | lock |    script b
---------------------+------+-----------------
start

open session      <- | yes  |    start

do stuff

close session     -> | yes  | -> open session

do heavy queries     |      |    do stuff

open session      <- | yes  | <- script ended

script ended      -> | no   |

当你不打算使用它时关闭会话,暂时或者直到脚本结束,使其可用于另一个脚本。

请注意,一旦其他脚本运行,会话数据可能已被更改。