| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- import warnings
- from django.core.exceptions import MiddlewareNotUsed
- from django.db import connection, transaction
- from django.utils.deprecation import RemovedInDjango18Warning
- class TransactionMiddleware(object):
- """
- Transaction middleware. If this is enabled, each view function will be run
- with commit_on_response activated - that way a save() doesn't do a direct
- commit, the commit is done when a successful response is created. If an
- exception happens, the database is rolled back.
- """
- def __init__(self):
- warnings.warn(
- "TransactionMiddleware is deprecated in favor of ATOMIC_REQUESTS.",
- RemovedInDjango18Warning, stacklevel=2)
- if connection.settings_dict['ATOMIC_REQUESTS']:
- raise MiddlewareNotUsed
- def process_request(self, request):
- """Enters transaction management"""
- transaction.enter_transaction_management()
- 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()
- def process_response(self, request, response):
- """Commits and leaves transaction management."""
- if not transaction.get_autocommit():
- if transaction.is_dirty():
- # 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
|