summaryrefslogtreecommitdiff
path: root/django/middleware
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2013-02-05 23:52:29 +0200
committerAnssi Kääriäinen <akaariai@gmail.com>2013-02-10 13:55:54 +0200
commita4e97cf315142e61bb4bc3ed8259b95d8586d09c (patch)
tree7f21b7043e9a05a2dae6d8c833f98cb68f1c7fc9 /django/middleware
parent0e18fb04bad99de237b5eb8ea4f9ff2f3cd147d3 (diff)
Fixed #19707 -- Reset transaction state after requests
Diffstat (limited to 'django/middleware')
-rw-r--r--django/middleware/transaction.py21
1 files changed, 20 insertions, 1 deletions
diff --git a/django/middleware/transaction.py b/django/middleware/transaction.py
index 96b1538d9d..4440f377a7 100644
--- a/django/middleware/transaction.py
+++ b/django/middleware/transaction.py
@@ -15,6 +15,10 @@ class TransactionMiddleware(object):
def process_exception(self, request, exception):
"""Rolls back the database and leaves transaction management"""
if transaction.is_dirty():
+ # This rollback might fail because of network failure for example.
+ # If rollback isn't possible it is impossible to clean the
+ # connection's state. So leave the connection in dirty state and
+ # let request_finished signal deal with cleaning the connection.
transaction.rollback()
transaction.leave_transaction_management()
@@ -22,6 +26,21 @@ class TransactionMiddleware(object):
"""Commits and leaves transaction management."""
if transaction.is_managed():
if transaction.is_dirty():
- transaction.commit()
+ # Note: it is possible that the commit fails. If the reason is
+ # closed connection or some similar reason, then there is
+ # little hope to proceed nicely. However, in some cases (
+ # deferred foreign key checks for exampl) it is still possible
+ # to rollback().
+ try:
+ transaction.commit()
+ except Exception:
+ # If the rollback fails, the transaction state will be
+ # messed up. It doesn't matter, the connection will be set
+ # to clean state after the request finishes. And, we can't
+ # clean the state here properly even if we wanted to, the
+ # connection is in transaction but we can't rollback...
+ transaction.rollback()
+ transaction.leave_transaction_management()
+ raise
transaction.leave_transaction_management()
return response