Permalink
Browse files

Added some assertions to enforce the atomicity of atomic.

  • Loading branch information...
1 parent d7bc4fb commit 7c46c8d5f27fe305507359588ca0635b6d87c59a @aaugustin aaugustin committed Mar 4, 2013
@@ -70,6 +70,7 @@ def reset_queries(**kwargs):
# their lifetime. NB: abort() doesn't do anything outside of a transaction.
def close_old_connections(**kwargs):
for conn in connections.all():
+ # Remove this when the legacy transaction management goes away.
try:
conn.abort()
except DatabaseError:
@@ -157,6 +157,7 @@ def commit(self):
Commits a transaction and resets the dirty flag.
"""
self.validate_thread_sharing()
+ self.validate_no_atomic_block()
self._commit()
self.set_clean()
@@ -165,6 +166,7 @@ def rollback(self):
Rolls back a transaction and resets the dirty flag.
"""
self.validate_thread_sharing()
+ self.validate_no_atomic_block()
self._rollback()
self.set_clean()
@@ -265,6 +267,8 @@ def enter_transaction_management(self, managed=True, forced=False):
If you switch off transaction management and there is a pending
commit/rollback, the data will be commited, unless "forced" is True.
"""
+ self.validate_no_atomic_block()
+
self.transaction_state.append(managed)
if not managed and self.is_dirty() and not forced:
@@ -280,6 +284,8 @@ def leave_transaction_management(self):
over to the surrounding block, as a commit will commit all changes, even
those from outside. (Commits are on connection level.)
"""
+ self.validate_no_atomic_block()
+
if self.transaction_state:
del self.transaction_state[-1]
else:
@@ -305,10 +311,19 @@ def set_autocommit(self, autocommit=True):
"""
Enable or disable autocommit.
"""
+ self.validate_no_atomic_block()
self.ensure_connection()
self._set_autocommit(autocommit)
self.autocommit = autocommit
+ def validate_no_atomic_block(self):
+ """
+ Raise an error if an atomic block is active.
+ """
+ if self.in_atomic_block:
+ raise TransactionManagementError(
+ "This is forbidden when an 'atomic' block is active.")
+
def abort(self):
"""
Roll back any ongoing transaction and clean the transaction state
@@ -367,6 +367,9 @@ def autocommit(using=None):
this decorator is useful if you globally activated transaction management in
your settings file and want the default behavior in some view functions.
"""
+ warnings.warn("autocommit is deprecated in favor of set_autocommit.",
+ PendingDeprecationWarning, stacklevel=2)
+
def entering(using):
enter_transaction_management(managed=False, using=using)
@@ -382,6 +385,9 @@ def commit_on_success(using=None):
a rollback is made. This is one of the most common ways to do transaction
control in Web apps.
"""
+ warnings.warn("commit_on_success is deprecated in favor of atomic.",
+ PendingDeprecationWarning, stacklevel=2)
+
def entering(using):
enter_transaction_management(using=using)
@@ -409,6 +415,9 @@ def commit_manually(using=None):
own -- it's up to the user to call the commit and rollback functions
themselves.
"""
+ warnings.warn("commit_manually is deprecated in favor of set_autocommit.",
+ PendingDeprecationWarning, stacklevel=2)
+
def entering(using):
enter_transaction_management(using=using)
@@ -420,10 +429,15 @@ def exiting(exc_value, using):
def commit_on_success_unless_managed(using=None):
"""
Transitory API to preserve backwards-compatibility while refactoring.
+
+ Once the legacy transaction management is fully deprecated, this should
+ simply be replaced by atomic. Until then, it's necessary to avoid making a
+ commit where Django didn't use to, since entering atomic in managed mode
+ triggers a commmit.
"""
connection = get_connection(using)
- if connection.autocommit and not connection.in_atomic_block:
- return commit_on_success(using)
+ if connection.autocommit or connection.in_atomic_block:
+ return atomic(using)
else:
def entering(using):
pass
@@ -329,6 +329,10 @@ these changes.
1.8
---
+* The decorators and context managers ``django.db.transaction.autocommit``,
+ ``commit_on_success`` and ``commit_manually`` will be removed. See
+ :ref:`transactions-upgrading-from-1.5`.
+
* The :ttag:`cycle` and :ttag:`firstof` template tags will auto-escape their
arguments. In 1.6 and 1.7, this behavior is provided by the version of these
tags in the ``future`` template tag library.
@@ -105,16 +105,14 @@ you just won't get any of the nice new unittest2 features.
Transaction context managers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Users of Python 2.5 and above may now use :ref:`transaction management functions
-<transaction-management-functions>` as `context managers`_. For example::
+Users of Python 2.5 and above may now use transaction management functions as
+`context managers`_. For example::
with transaction.autocommit():
# ...
.. _context managers: http://docs.python.org/glossary.html#term-context-manager
-For more information, see :ref:`transaction-management-functions`.
-
Configurable delete-cascade
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -148,16 +148,14 @@ you just won't get any of the nice new unittest2 features.
Transaction context managers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Users of Python 2.5 and above may now use :ref:`transaction management functions
-<transaction-management-functions>` as `context managers`_. For example::
+Users of Python 2.5 and above may now use transaction management functions as
+`context managers`_. For example::
with transaction.autocommit():
# ...
.. _context managers: http://docs.python.org/glossary.html#term-context-manager
-For more information, see :ref:`transaction-management-functions`.
-
Configurable delete-cascade
~~~~~~~~~~~~~~~~~~~~~~~~~~~
View
@@ -39,7 +39,7 @@ should improve performance. The existing APIs were deprecated, and new APIs
were introduced, as described in :doc:`/topics/db/transactions`.
Please review carefully the list of :ref:`known backwards-incompatibilities
-<transactions-changes-from-1.5>` to determine if you need to make changes in
+<transactions-upgrading-from-1.5>` to determine if you need to make changes in
your code.
Persistent database connections
@@ -163,7 +163,7 @@ Backwards incompatible changes in 1.6
* Database-level autocommit is enabled by default in Django 1.6. While this
doesn't change the general spirit of Django's transaction management, there
are a few known backwards-incompatibities, described in the :ref:`transaction
- management docs <transactions-changes-from-1.5>`. You should review your code
+ management docs <transactions-upgrading-from-1.5>`. You should review your code
to determine if you're affected.
* In previous versions, database-level autocommit was only an option for
@@ -256,6 +256,19 @@ Backwards incompatible changes in 1.6
Features deprecated in 1.6
==========================
+Transaction management APIs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Transaction management was completely overhauled in Django 1.6, and the
+current APIs are deprecated:
+
+- :func:`django.db.transaction.autocommit`
+- :func:`django.db.transaction.commit_on_success`
+- :func:`django.db.transaction.commit_manually`
+
+The reasons for this change and the upgrade path are described in the
+:ref:`transactions documentation <transactions-upgrading-from-1.5>`.
+
Changes to :ttag:`cycle` and :ttag:`firstof`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Oops, something went wrong. Retry.

0 comments on commit 7c46c8d

Please sign in to comment.