我在django会话中挣扎了一天,似乎在没有编写自己的会话中间件或使用某些锁定的情况下我无法解决它。问题是,即使手动触发保存,也不会存储会话。它偶尔会发生,因为当从客户端发送多个同时发送的AJAX请求时会发生竞争条件。我正在使用db后端。问题是,当从javascript端调用一个start()dajaxice调用时,一切正常。
所以问题是,为什么有时会存储会话?我应该锁定存储会话的段吗?我仔细检查session_key仍然是一样的。不应该在会话中间件模块中解决这个问题吗?
设置: SESSION_SAVE_EVERY_REQUEST = True
def print_session_keys(request, tmp):
session_key = request.session.session_key
session = Session.objects.get(session_key=session_key)
a = session.get_decoded()
print tmp+str(a.keys())
@dajaxice_register
def start(request):
dajax = Dajax()
searchHash = os.urandom(16).encode('hex')
data = 1
print_session_keys(request, 'Before: - hash: '+searchHash+' ')
request.session.set_expiry(0)
request.session[searchHash] = data
request.session.modified = True
request.session.save()
print_session_keys(request, 'After: - hash: '+searchHash+' ')
LOG:
1或2个3的请求,存储正常:
之前: - 哈希:05f22e8e828a0e6145519e0bb0778357 [u'b0d0d5e4ebe846c4e3ffa66bfbd2e7e3' , u'usermode',u'_session_expiry']之后: - 哈希: 05f22e8e828a0e6145519e0bb0778357 [u'09cf89e0cbe5fb6a179e1f658d452c6b”, u'05f22e8e828a0e6145519e0bb0778357',u'usermode', 你好了,u'_session_expiry']
BUT:
之前: - 哈希:071e79041aba16a82a32fe4a77c3b4e0 [u'b0d0d5e4ebe846c4e3ffa66bfbd2e7e3' , u'usermode',u'_session_expiry']
之后: - 哈希:071e79041aba16a82a32fe4a77c3b4e0 [u'09cf89e0cbe5fb6a179e1f658d452c6b”, u'05f22e8e828a0e6145519e0bb0778357',u'usermode', 你好了,u'_session_expiry']
更新
我最终使用了mutex.acquire()和mutex.release()。它现在有效,但必须捕获所有异常,否则互斥不会被释放。
mutex.acquire()
try:
request.session.set_expiry(0)
request.session[searchHash] = data
request.session.modified = True
request.session.save()
except SomeException:
mutex.release()
return dajax.json()
mutex.release()
因此,如果您正在执行多个具有相同session_key的请求,则需要使用一些锁定。在django进入视图之前获取会话数据。这就是为什么会话的多个和不同实例与同一个session_key共存的原因。所以简要描述一下发生了什么:
1)请求1从db中获取会话数据
2)请求1点击视图
3)请求2从db中获取会话数据
4)请求2点击视图
5)请求2保存会话[mykey]
6)请求1保存从<1>获取的 OLD 会话数据并覆盖5)中写入的会话
我希望这对某些人有帮助。