数据库中的PHP Session,“同时”运行,覆盖

时间:2017-08-11 07:24:33

标签: php session

我将会话存储在数据库中,因为有5个不同的服务器需要共享它。

我的经验是,session_start从数据库中读取会话,当php文件的执行结束时,它会被写回数据库。

首先让我们说会话内容是['data1'=> 0,'data2'=>我有两个ajax文件:ajax1.php,将data1设置为1,ajax2.php将data2设置为2。

他们同时跑步:
ajax1.php ----------------------
ajax2.php -------------
(所以ajax2稍后开始运行,但提前结束)

在上面提到的情况中,分别发生以下情况:

  1. ajax1从db:data1 == 0和data2 == 0
  2. 读取会话
  3. ajax2从db:data1 == 0和data2 == 0
  4. 读取会话
  5. ajax1设置其“本地”超全球$ _SESSION:data1 = 1
  6. ajax2设置其“本地”超全球$ _SESSION:data2 = 2
  7. ajax2将会话写入数据库['data1'=> 0,'data2'=> 2]
  8. ajax1将会话写入数据库['data1'=> 1,'data2'=> 0]
  9. 这导致他们在运行会话后包含['data1'=> 1,'data2'=> 0]当['data1'=> 1,'data2'=> 2]是预期的。

    这是我的问题,我需要帮助:

    • 有人遇到过同样的情况吗?
    • 发生这种情况是“正常”,还是我的实施必须有问题?
    • 当然,我应该如何处理这种情况?
    • 欢迎所有其他经验,想法和材料。

    谢谢。

2 个答案:

答案 0 :(得分:0)

我建议你不要用每个ajax编写整个会话,只是你改变的数据。如果ajax1专用于data1,那么它根本不应该触及data2,对于data1而言ajax2也是如此。

修改

重构一下逻辑。仅在$_SESSION中存储在数据库,Memcached或Redis层中查找信息所需的信息。使用会话密钥或您在$_SESSION中放入的其他一些唯一标识符来访问您在另一个表或存储技术中手动写入的数据。由于它的会话数据,它并不意味着重新启动,并且不需要在每台服务器上写入磁盘。我建议使用memcached,因为它易于使用,而且非常快。

实施例: See example architecture here

答案 1 :(得分:0)

这是HHVM在某些情况下比PHP7更快的原因之一,因为它不会锁定会话文件。

阅读此有用的问答:

PHP & Sessions: Is there any way to disable PHP session locking?

似乎总有某种竞争条件。

一旦您不再编写数据,使用session_write_close()可能会有所帮助。

最终的解决方案是编写自己的会话处理程序而不使用PHP内部会话功能。然后,您可以最大程度地控制会话和锁定。

看看PHP.net上的这条评论,它准确描述了你的问题:

http://php.net/manual/en/function.session-set-save-handler.php#49630

您还可以尝试以不同方式实现MySQL会话处理程序并添加锁支持。