概要: Django セッションに競合状態はありますか?どうすれば回避できますか?
同じユーザーによる同時リクエストによる競合状態が関係していると思われる Django セッションに関する興味深い問題があります。
複数のファイルを同時にアップロードするスクリプトで発生し、localhost でテストされています。これにより、同じユーザーからの同時リクエストが発生する可能性が非常に高いと思います(ローカルホストによる応答時間の短縮、ファイルのアップロードによる長いリクエスト)。ただし、localhost 以外の通常のリクエストは可能ですが、可能性は低くなります。
これを行うと思われるいくつかの(ファイル投稿)リクエストを送信しています:
- Django はユーザーのセッションを自動的に取得します*
- 時間がかかる無関係なコード
- 取得
request.session['files']
(辞書) - 現在のファイルに関するデータを辞書に追加します
- 辞書を
request.session['files']
再度格納する - 本当に保存されているか確認する
- 時間がかかる無関係なコードの増加
- Django はユーザーのセッションを自動的に保存します
ここで 6. のチェックは、情報が実際にセッションに保存されたことを示します。ただし、将来の要求は、ある場合とない場合があることを示しています。
私が考えているのは、これらの要求のうち 2 つ (A と B) が同時に発生していることです。リクエスト Arequest.session['files']
が最初に取得し、次に B が同じことを行い、変更して保存します。A が最終的に終了すると、B によるセッションの変更が上書きされます。
2 つの質問:
- これは本当に起こっていることですか?django 開発サーバーはマルチスレッドですか? Google で、マルチスレッド化に関するページを見つけましたが、デフォルトではそうではないことを示唆していますか? それ以外の場合、何が問題になる可能性がありますか?
- この競合状態が問題である場合、それを解決する最善の方法は何でしょうか? 不便ではありますが、セキュリティ上の問題ではないので、その可能性を大幅に減らすことができれば幸いです.
変更の直前にセッションデータを取得し、直後に保存すると、チャンスが大幅に減少すると思います。request.session
ただし、 でこれを行う方法は見つかりませんでしたdjango.contrib.sessions.backends.db.SessionStore
。ただし、そのように変更すると、Django はrequest.session
リクエストの最後に上書きするだけだと思います。
したがって、基本的にrequest.session.reload()
andが必要です。request.session.commit()