2010-07-23 133 views
0

我有一个特殊的问题,使同时发生的AJAX请求修改会话中存储的PHP对象。我遇到了竞争条件问题,但我不明白为什么会发生这种情况......只有一次AJAX调用可以一次打开会话,所以如果他们在进行修改时保持会话打开,则不应该请致电能够看到其他人所做的更改?下面是流程的简化版本(A和B是两组参数):同时AJAX请求和PHP会话

1)发起运行启动(A)的AJAX调用。此通话打开会话。它通过向数组添加“A - Running”来更新PHP对象。
2)对Run(A)进行AJAX调用。它等到Initiate(A)关闭会话后再运行。它短暂地打开会话,但明确地关闭它并且不修改对象。运行(A)将需要长达60秒的时间才能运行。
3)另一个运行启动(B)的AJAX调用。这将打开会话并通过向数组添加“B - Running”来修改对象。
4)另一个AJAX调用是运行(B)。它简要地打开会话,但明确地关闭它。

到目前为止,一切都很好。运行(A)和运行(B)都在执行。 “A - 正在运行”和“B - 正在运行”都在对象的数组中,存储在未在任何请求中打开的会话中。这里是有趣的地方:

5)运行(A)完成第一个执行,并进行AJAX调用运行Show(A)。这将打开会话,检索对象,并将“A - 正在运行”更改为“A-完成”。有趣的是,“跑步 - B”根本就没有。
6)当Run(B)结束时,会执行一个AJAX调用来执行Show(B)。这将打开会话并检索对象。它将“B - 运行”更改为“B - 完成”。然而,数组中的第一个元素是“A - 正在运行”。

如果会话关闭并保存,当Show(A)打开它时,它为什么看不到Initiate(B)所做的更改?当启动(B)可以清楚地看到启动(A)所做的更改,但显示(B)不能看到显示(A)所做的更改...

如果运行(B)润(A)。

+0

你碰巧使用自己的会话处理程序,而不是使用磁盘上的文件的默认会话处理程序? – Charles 2010-07-23 20:18:53

+0

我们使用了一个外部框架(eyeOS),但在代码中的任何地方都看不到session_set_save_handler的调用。没有其他方式可以使用自定义会话处理程序吗? 我也看到服务器上的/ tmp/sess_(我的session_id)。 – Derek 2010-07-23 20:56:28

+0

然后,您可能正在使用基于文件的会话系统。听起来像这是一个自定义会话处理程序和数据库锁定的情况,但现在我不太确定。 – Charles 2010-07-23 21:12:07

回答

1

它似乎与eyeOS框架有关。看起来,因为我在我的Run函数开始时执行了session_write_close(),所以我必须在我的Run函数结束时使用session_start(),否则eyeOS无法正确清理或执行某些操作。

我一直在为此工作3天。故事的道德:不要使用eyeOS进行开发!