2010-07-23 131 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進行開發!