Thinking out loud: You can't just lock the session when you think you have a critical section of code in a view because the session data is stored in one field in the database, and is
completely overwritten on write. Consider this case:
Thread A: Read session data
Thread B: Open transaction, read session (with lock) data, add session['foo'] = 1, write session back to database, close transaction.
Thread A: session['bar'] = 1, save session (completely overwriting Thread B's changes so 'foo' doesn't exist anymore)
So any view that will write to the session *must* lock it before reading. And like Stephen is saying, you don't want to do that on every request. I suppose you could keep session reads as-is. But any time you need to do a write, you must explicitly wrap it in a transaction, and refresh the data from the database (while locking other writers):
...
# freely read any session data (but it could be stale)
...
# now we need to write something to the session
with transaction.atomic():
# the session data needs to be refresh if it was updated by another transaction after it was first read by this thread
request.session.lock_and_refresh()
if request.session.get('has_commented', False):
request.session['has_commented'] = True
...
request.session.save()Session implementations could provide a context manager (if they support atomic writes) so it's not so ugly:
with request.session.atomic():
if request.session.get("has_commented", False):
request.session['has_commented'] = True
...
But EVERY session write must follow that pattern, or it's all for naught. I don't think Django core uses sessions much, so updating core doesn't sound bad. It's everyone downstream. That seems totally impractical. I do think there are some very subtle bugs that would be resolved by adopting something like this. But it may not be worth the trouble.