“数据库中的PHP会话”;“同时”;运行、覆盖

“数据库中的PHP会话”;“同时”;运行、覆盖,php,session,Php,Session,我将会话存储在数据库中,因为有5个不同的服务器需要共享它 我的经验是,session_start从数据库读取会话,并在php文件执行结束时将其写回数据库 假设最初会话内容是['data1'=>0,'data2'=>0],我有两个ajax文件:ajax1.php,将data1设置为1,ajax2.php将data2设置为2 它们像这样同时运行: ajax1.php----------------- ajax2.php----------------- (因此ajax2开始运行得晚,但完成得早) 在

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

我的经验是,session_start从数据库读取会话,并在php文件执行结束时将其写回数据库

假设最初会话内容是['data1'=>0,'data2'=>0],我有两个ajax文件:ajax1.php,将data1设置为1,ajax2.php将data2设置为2

它们像这样同时运行:
ajax1.php-----------------
ajax2.php-----------------
(因此ajax2开始运行得晚,但完成得早)

在上述情况下,分别发生以下情况:

  • ajax1从db读取会话:data1==0和data2==0
  • ajax2从db:data1==0和data2==0读取会话
  • ajax1设置其“本地”超全局$\会话:data1=1
  • ajax2设置其“本地”超全局$\会话:data2=2
  • ajax2将会话写入数据库['data1'=>0,'data2'=>2]
  • ajax1将会话写入数据库['data1'=>1,'data2'=>0]
  • 这导致在运行会话后,会话包含['data1'=>1,'data2'=>0],而预期为['data1'=>1,'data2'=>2]

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

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

    谢谢。

    我建议您不要使用每个ajax编写整个会话,只编写您更改的数据。如果ajax1专用于data1,那么它就不应该接触data2,对于data1,ajax2也是如此

    编辑 稍微重构一下逻辑。仅将在数据库、Memcached或Redis层中查找信息所需的信息存储在
    $\u会话中。使用会话密钥或您在
    $\u session
    中输入的其他唯一标识符来访问手动写入另一个表或存储技术中的数据。由于它的会话数据,它不意味着能够在重新启动后生存,也不需要写入每台服务器上的磁盘。我推荐memcached begause,因为它易于使用,而且速度非常快

    例如:

    我建议您不要使用每个ajax编写整个会话,只编写您更改的数据。如果ajax1专用于data1,那么它就不应该接触data2,对于data1,ajax2也是如此

    编辑 稍微重构一下逻辑。仅将在数据库、Memcached或Redis层中查找信息所需的信息存储在
    $\u会话中。使用会话密钥或您在
    $\u session
    中输入的其他唯一标识符来访问手动写入另一个表或存储技术中的数据。由于它的会话数据,它不意味着能够在重新启动后生存,也不需要写入每台服务器上的磁盘。我推荐memcached begause,因为它易于使用,而且速度非常快

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

    阅读以下有用的问答:

    似乎总有某种比赛条件

    一旦不再写入数据,使用
    session\u write\u close()
    可能会有所帮助

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

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


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

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

    阅读以下有用的问答:

    似乎总有某种比赛条件

    一旦不再写入数据,使用
    session\u write\u close()
    可能会有所帮助

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

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


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

    我认为您可以使用NFS存储会话,并跨不同的服务器(从同一NFS)读取会话。@CvetomirLazarov不确定NFS是否正确使用文件锁/会话锁。@danfrom我想您是对的。我的缺点:(这里有一个好的解读:我认为您可以使用NFS存储会话并跨不同的服务器(从相同的NFS)读取它)。@CvetomirLazarov不确定NFS是否正确使用文件锁/会话锁。@Danfrom Germany我想您是对的。我的缺点:(下面是一篇好文章:您将如何实现它?PHP会话只是
    serialize()
    $\u SESSION
    并将其刷新到存储中。它在会话全局中的单个键值对之间没有区别。@DanFromGermany稍微重构一下逻辑。在会话中只存储在数据库、memcached或Redis层中查找信息所需的信息。使用会话密钥或其他存储的唯一标识符通过PHP在会话数据库中访问手动写入另一个表或存储技术中的数据。由于其会话,我建议使用memcached。由于有5个不同的服务器,memcached中存储的数据应该共享,否?@SteveGeorge是的,所有服务器都将与memcached服务器通信。@SteveGeorge看到我添加的图像了吗实现这一点?PHP会话只需序列化()$\u SESSION并将其刷新到存储中。它不会