transaction.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import warnings
  2. from django.core.exceptions import MiddlewareNotUsed
  3. from django.db import connection, transaction
  4. from django.utils.deprecation import RemovedInDjango18Warning
  5. class TransactionMiddleware(object):
  6. """
  7. Transaction middleware. If this is enabled, each view function will be run
  8. with commit_on_response activated - that way a save() doesn't do a direct
  9. commit, the commit is done when a successful response is created. If an
  10. exception happens, the database is rolled back.
  11. """
  12. def __init__(self):
  13. warnings.warn(
  14. "TransactionMiddleware is deprecated in favor of ATOMIC_REQUESTS.",
  15. RemovedInDjango18Warning, stacklevel=2)
  16. if connection.settings_dict['ATOMIC_REQUESTS']:
  17. raise MiddlewareNotUsed
  18. def process_request(self, request):
  19. """Enters transaction management"""
  20. transaction.enter_transaction_management()
  21. def process_exception(self, request, exception):
  22. """Rolls back the database and leaves transaction management"""
  23. if transaction.is_dirty():
  24. # This rollback might fail because of network failure for example.
  25. # If rollback isn't possible it is impossible to clean the
  26. # connection's state. So leave the connection in dirty state and
  27. # let request_finished signal deal with cleaning the connection.
  28. transaction.rollback()
  29. transaction.leave_transaction_management()
  30. def process_response(self, request, response):
  31. """Commits and leaves transaction management."""
  32. if not transaction.get_autocommit():
  33. if transaction.is_dirty():
  34. # Note: it is possible that the commit fails. If the reason is
  35. # closed connection or some similar reason, then there is
  36. # little hope to proceed nicely. However, in some cases (
  37. # deferred foreign key checks for exampl) it is still possible
  38. # to rollback().
  39. try:
  40. transaction.commit()
  41. except Exception:
  42. # If the rollback fails, the transaction state will be
  43. # messed up. It doesn't matter, the connection will be set
  44. # to clean state after the request finishes. And, we can't
  45. # clean the state here properly even if we wanted to, the
  46. # connection is in transaction but we can't rollback...
  47. transaction.rollback()
  48. transaction.leave_transaction_management()
  49. raise
  50. transaction.leave_transaction_management()
  51. return response