摘要:有沒有在Django會話的競爭條件,以及如何預防呢?Django會話競賽狀態?
我有,我認爲涉及的競爭條件由於同一用戶的併發請求的Django會話一個有趣的問題。
它發生在同時上傳多個文件的腳本,在本地主機上進行測試。我認爲這會使得來自同一用戶的同時請求很有可能(由於本地主機的響應時間較短,文件上傳導致請求較長)。儘管如此,對於localhost之外的普通請求仍然是可能的,只是不太可能。
我派幾個(文件後)的請求,我認爲這樣做:
- Django的自動檢索用戶的會話*
- 無關的代碼需要一些時間
- 獲取
request.session['files']
(一字典) - 將關於當前文件的數據追加到字典
- 將字典存儲在
request.session['files']
a獲得 - 檢查確實已經存儲
- 更多不相關的代碼,需要時間
- Django的自動存儲用戶的會話
在此間舉行6.檢查將指示信息確實已存儲在會話中。但是,未來的請求表明有時它有,有時它沒有。
我認爲正在發生的是,其中兩個請求(A和B)的同時發生。請求A首先檢索request.session['files']
,然後B執行相同的操作,更改並存儲它。當A終於完成後,它會覆蓋B.
兩個問題:
- 這確實是發生了什麼事? django開發服務器是多線程的嗎?在Google上,我找到了關於使其成爲多線程的頁面,暗示默認情況下它不是?否則,可能是什麼問題?
- 如果這場比賽條件的問題,這將是解決這個問題的最好方法?這是一個不便,但不是一個安全問題,所以如果機會可以大大減少,我已經很高興。
在更改之前檢索會話數據並在之後保存它應該會顯着降低機會我認爲。但是,我還沒有找到一種方法來爲request.session
做這個,只能用django.contrib.sessions.backends.db.SessionStore
來解決這個問題。不過,我認爲如果我改變這種方式,Django將在請求結束時用request.session
覆蓋它。
所以我基本上需要一個request.session.reload()
和request.session.commit()
。
不知道爲什麼,但會話重新加載無法正常工作,即使之前有睡眠。不過,數據庫解決方案的功能非常好,值得額外購買。 – Mark