diff options
| author | Aymeric Augustin <aymeric.augustin@m4x.org> | 2013-03-04 23:26:31 +0100 |
|---|---|---|
| committer | Aymeric Augustin <aymeric.augustin@m4x.org> | 2013-03-11 14:48:55 +0100 |
| commit | 7c46c8d5f27fe305507359588ca0635b6d87c59a (patch) | |
| tree | ca99a91cedfd6d8d03a3fbe334ee9589a51ef002 /django | |
| parent | d7bc4fbc94df6c231d71dffa45cf337ff13512ee (diff) | |
Added some assertions to enforce the atomicity of atomic.
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/__init__.py | 1 | ||||
| -rw-r--r-- | django/db/backends/__init__.py | 15 | ||||
| -rw-r--r-- | django/db/transaction.py | 18 |
3 files changed, 32 insertions, 2 deletions
diff --git a/django/db/__init__.py b/django/db/__init__.py index 13ba68ba7e..08c901ab7b 100644 --- a/django/db/__init__.py +++ b/django/db/__init__.py @@ -70,6 +70,7 @@ signals.request_started.connect(reset_queries) # 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: diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index 818850bf43..346d10198d 100644 --- a/django/db/backends/__init__.py +++ b/django/db/backends/__init__.py @@ -157,6 +157,7 @@ class BaseDatabaseWrapper(object): 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 @@ class BaseDatabaseWrapper(object): 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 @@ class BaseDatabaseWrapper(object): 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 @@ class BaseDatabaseWrapper(object): 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 @@ class BaseDatabaseWrapper(object): """ 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 diff --git a/django/db/transaction.py b/django/db/transaction.py index 8126c18a70..eb9d85e274 100644 --- a/django/db/transaction.py +++ b/django/db/transaction.py @@ -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 commit_manually(using=None): 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 |
