Zend_Session_SaveHandler_DbTable和并发请求

时间:2011-03-02 00:52:03

标签: php zend-framework session

我目前正在使用Zend_Session_SaveHandler_DbTable在多台计算机上共享会话数据。

我遇到了并发请求的问题,如下例所示。请求A和B同时为同一用户运行

  1. 请求A - 读入用户的会话数据
  2. 请求B - 读取用户的会话数据
  3. 请求B - 通过向会话添加变量xyz并将会话数据写回数据库来完成
  4. 请求A - 完成原始会话值并将其写回数据库
  5. 结果。我们丢失了xyz变量。请注意,即使请求A未更改会话变量,它也会写回数据库。我认为这是因为它需要更新会话的修改时间。

    归结为请求A不会锁定会话,看起来Zend_Session_SaveHandler_DbTable不支持会话锁定。有没有人有任何关于如何解决这个问题的例子?使用memcached或返回基于文件的会话不是一种选择。

    目前我已经攻击了Zend_Session_SaveHandler_DbTable写入方法来比较读取和写入时的修改日期,如果不同,请不要将会话写回数据库。

1 个答案:

答案 0 :(得分:0)

您看到的行为符合预期。 (这并不意味着它不会吮吸。)

默认的基于文件的会话处理程序实际上在session_startsession_write_close / script end之间的会话文件上保持独占锁。这样只允许用户的一个请求立即运行。

PHP开发人员似乎希望每个自定义会话处理程序独立处理锁定问题。这不是没有道理的,但这是一个痛苦的屁股。

您正在使用的解决方案可能是安全和理智的。它也优于尝试在SQL中建立锁定,当脚本异常退出并且无法释放锁定时,这会很麻烦。您应该考虑充实自定义代码以使锁定可选,然后将该代码提交给Zend Framework项目,以便其他人可以从中受益。