我已经失去了一天与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'b0d0d5e4ebe846c4e3ffa66bfbd2e7e3' , u'_session_expiry']

但:

前: - 哈希:071e79041aba16a82a32fe4a77c3b4e0 [u'b0d0d5e4ebe846c4e3ffa66bfbd2e7e3' ,u'usermode 'u'_session_expiry ']之后: - 哈希:071e79041aba16a82a32fe4a77c3b4e0 [u'09cf89e0cbe5fb6a179e1f658d452c6b',u'05f22e8e828a0e6145519e0bb0778357' ,u'usermode',u'b0d0d5e4ebe846c4e3ffa66bfbd2e7e3' , u'_session_expiry']

UPDATE:

我最终使用了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)中写入的会话

我希望这可能对某人有所帮助 .