mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	Deprecated transaction.commit/rollback_unless_managed.
Since "unless managed" now means "if database-level autocommit", committing or rolling back doesn't have any effect. Restored transactional integrity in a few places that relied on automatically-started transactions with a transitory API.
This commit is contained in:
		| @@ -555,10 +555,6 @@ class LayerMapping(object): | |||||||
|                     except SystemExit: |                     except SystemExit: | ||||||
|                         raise |                         raise | ||||||
|                     except Exception as msg: |                     except Exception as msg: | ||||||
|                         if self.transaction_mode == 'autocommit': |  | ||||||
|                             # Rolling back the transaction so that other model saves |  | ||||||
|                             # will work. |  | ||||||
|                             transaction.rollback_unless_managed() |  | ||||||
|                         if strict: |                         if strict: | ||||||
|                             # Bailing out if the `strict` keyword is set. |                             # Bailing out if the `strict` keyword is set. | ||||||
|                             if not silent: |                             if not silent: | ||||||
|   | |||||||
| @@ -74,7 +74,6 @@ class SessionStore(SessionBase): | |||||||
|     @classmethod |     @classmethod | ||||||
|     def clear_expired(cls): |     def clear_expired(cls): | ||||||
|         Session.objects.filter(expire_date__lt=timezone.now()).delete() |         Session.objects.filter(expire_date__lt=timezone.now()).delete() | ||||||
|         transaction.commit_unless_managed() |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # At bottom to avoid circular import | # At bottom to avoid circular import | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								django/core/cache/backends/db.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								django/core/cache/backends/db.py
									
									
									
									
										vendored
									
									
								
							| @@ -10,7 +10,7 @@ except ImportError: | |||||||
|  |  | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.core.cache.backends.base import BaseCache | from django.core.cache.backends.base import BaseCache | ||||||
| from django.db import connections, router, transaction, DatabaseError | from django.db import connections, router, DatabaseError | ||||||
| from django.utils import timezone, six | from django.utils import timezone, six | ||||||
| from django.utils.encoding import force_bytes | from django.utils.encoding import force_bytes | ||||||
|  |  | ||||||
| @@ -70,7 +70,6 @@ class DatabaseCache(BaseDatabaseCache): | |||||||
|             cursor = connections[db].cursor() |             cursor = connections[db].cursor() | ||||||
|             cursor.execute("DELETE FROM %s " |             cursor.execute("DELETE FROM %s " | ||||||
|                            "WHERE cache_key = %%s" % table, [key]) |                            "WHERE cache_key = %%s" % table, [key]) | ||||||
|             transaction.commit_unless_managed(using=db) |  | ||||||
|             return default |             return default | ||||||
|         value = connections[db].ops.process_clob(row[1]) |         value = connections[db].ops.process_clob(row[1]) | ||||||
|         return pickle.loads(base64.b64decode(force_bytes(value))) |         return pickle.loads(base64.b64decode(force_bytes(value))) | ||||||
| @@ -124,10 +123,8 @@ class DatabaseCache(BaseDatabaseCache): | |||||||
|                                [key, b64encoded, connections[db].ops.value_to_db_datetime(exp)]) |                                [key, b64encoded, connections[db].ops.value_to_db_datetime(exp)]) | ||||||
|         except DatabaseError: |         except DatabaseError: | ||||||
|             # To be threadsafe, updates/inserts are allowed to fail silently |             # To be threadsafe, updates/inserts are allowed to fail silently | ||||||
|             transaction.rollback_unless_managed(using=db) |  | ||||||
|             return False |             return False | ||||||
|         else: |         else: | ||||||
|             transaction.commit_unless_managed(using=db) |  | ||||||
|             return True |             return True | ||||||
|  |  | ||||||
|     def delete(self, key, version=None): |     def delete(self, key, version=None): | ||||||
| @@ -139,7 +136,6 @@ class DatabaseCache(BaseDatabaseCache): | |||||||
|         cursor = connections[db].cursor() |         cursor = connections[db].cursor() | ||||||
|  |  | ||||||
|         cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key]) |         cursor.execute("DELETE FROM %s WHERE cache_key = %%s" % table, [key]) | ||||||
|         transaction.commit_unless_managed(using=db) |  | ||||||
|  |  | ||||||
|     def has_key(self, key, version=None): |     def has_key(self, key, version=None): | ||||||
|         key = self.make_key(key, version=version) |         key = self.make_key(key, version=version) | ||||||
| @@ -184,7 +180,6 @@ class DatabaseCache(BaseDatabaseCache): | |||||||
|         table = connections[db].ops.quote_name(self._table) |         table = connections[db].ops.quote_name(self._table) | ||||||
|         cursor = connections[db].cursor() |         cursor = connections[db].cursor() | ||||||
|         cursor.execute('DELETE FROM %s' % table) |         cursor.execute('DELETE FROM %s' % table) | ||||||
|         transaction.commit_unless_managed(using=db) |  | ||||||
|  |  | ||||||
| # For backwards compatibility | # For backwards compatibility | ||||||
| class CacheClass(DatabaseCache): | class CacheClass(DatabaseCache): | ||||||
|   | |||||||
| @@ -53,14 +53,13 @@ class Command(LabelCommand): | |||||||
|         for i, line in enumerate(table_output): |         for i, line in enumerate(table_output): | ||||||
|             full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or '')) |             full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or '')) | ||||||
|         full_statement.append(');') |         full_statement.append(');') | ||||||
|  |         with transaction.commit_on_success_unless_managed(): | ||||||
|             curs = connection.cursor() |             curs = connection.cursor() | ||||||
|             try: |             try: | ||||||
|                 curs.execute("\n".join(full_statement)) |                 curs.execute("\n".join(full_statement)) | ||||||
|             except DatabaseError as e: |             except DatabaseError as e: | ||||||
|             transaction.rollback_unless_managed(using=db) |  | ||||||
|                 raise CommandError( |                 raise CommandError( | ||||||
|                     "Cache table '%s' could not be created.\nThe error was: %s." % |                     "Cache table '%s' could not be created.\nThe error was: %s." % | ||||||
|                         (tablename, force_text(e))) |                         (tablename, force_text(e))) | ||||||
|             for statement in index_output: |             for statement in index_output: | ||||||
|                 curs.execute(statement) |                 curs.execute(statement) | ||||||
|         transaction.commit_unless_managed(using=db) |  | ||||||
|   | |||||||
| @@ -57,18 +57,17 @@ Are you sure you want to do this? | |||||||
|  |  | ||||||
|         if confirm == 'yes': |         if confirm == 'yes': | ||||||
|             try: |             try: | ||||||
|  |                 with transaction.commit_on_success_unless_managed(): | ||||||
|                     cursor = connection.cursor() |                     cursor = connection.cursor() | ||||||
|                     for sql in sql_list: |                     for sql in sql_list: | ||||||
|                         cursor.execute(sql) |                         cursor.execute(sql) | ||||||
|             except Exception as e: |             except Exception as e: | ||||||
|                 transaction.rollback_unless_managed(using=db) |  | ||||||
|                 raise CommandError("""Database %s couldn't be flushed. Possible reasons: |                 raise CommandError("""Database %s couldn't be flushed. Possible reasons: | ||||||
|   * The database isn't running or isn't configured correctly. |   * The database isn't running or isn't configured correctly. | ||||||
|   * At least one of the expected database tables doesn't exist. |   * At least one of the expected database tables doesn't exist. | ||||||
|   * The SQL was invalid. |   * The SQL was invalid. | ||||||
| Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run. | Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run. | ||||||
| The full error: %s""" % (connection.settings_dict['NAME'], e)) | The full error: %s""" % (connection.settings_dict['NAME'], e)) | ||||||
|             transaction.commit_unless_managed(using=db) |  | ||||||
|  |  | ||||||
|             # Emit the post sync signal. This allows individual |             # Emit the post sync signal. This allows individual | ||||||
|             # applications to respond as if the database had been |             # applications to respond as if the database had been | ||||||
|   | |||||||
| @@ -73,7 +73,6 @@ class Command(BaseCommand): | |||||||
|         # Start transaction management. All fixtures are installed in a |         # Start transaction management. All fixtures are installed in a | ||||||
|         # single transaction to ensure that all references are resolved. |         # single transaction to ensure that all references are resolved. | ||||||
|         if commit: |         if commit: | ||||||
|             transaction.commit_unless_managed(using=self.using) |  | ||||||
|             transaction.enter_transaction_management(using=self.using) |             transaction.enter_transaction_management(using=self.using) | ||||||
|  |  | ||||||
|         class SingleZipReader(zipfile.ZipFile): |         class SingleZipReader(zipfile.ZipFile): | ||||||
|   | |||||||
| @@ -83,6 +83,7 @@ class Command(NoArgsCommand): | |||||||
|         # Create the tables for each model |         # Create the tables for each model | ||||||
|         if verbosity >= 1: |         if verbosity >= 1: | ||||||
|             self.stdout.write("Creating tables ...\n") |             self.stdout.write("Creating tables ...\n") | ||||||
|  |         with transaction.commit_on_success_unless_managed(using=db): | ||||||
|             for app_name, model_list in manifest.items(): |             for app_name, model_list in manifest.items(): | ||||||
|                 for model in model_list: |                 for model in model_list: | ||||||
|                     # Create the model's database table, if it doesn't already exist. |                     # Create the model's database table, if it doesn't already exist. | ||||||
| @@ -102,8 +103,6 @@ class Command(NoArgsCommand): | |||||||
|                         cursor.execute(statement) |                         cursor.execute(statement) | ||||||
|                     tables.append(connection.introspection.table_name_converter(model._meta.db_table)) |                     tables.append(connection.introspection.table_name_converter(model._meta.db_table)) | ||||||
|  |  | ||||||
|         transaction.commit_unless_managed(using=db) |  | ||||||
|  |  | ||||||
|         # Send the post_syncdb signal, so individual apps can do whatever they need |         # Send the post_syncdb signal, so individual apps can do whatever they need | ||||||
|         # to do at this point. |         # to do at this point. | ||||||
|         emit_post_sync_signal(created_models, verbosity, interactive, db) |         emit_post_sync_signal(created_models, verbosity, interactive, db) | ||||||
| @@ -122,6 +121,7 @@ class Command(NoArgsCommand): | |||||||
|                     if custom_sql: |                     if custom_sql: | ||||||
|                         if verbosity >= 2: |                         if verbosity >= 2: | ||||||
|                             self.stdout.write("Installing custom SQL for %s.%s model\n" % (app_name, model._meta.object_name)) |                             self.stdout.write("Installing custom SQL for %s.%s model\n" % (app_name, model._meta.object_name)) | ||||||
|  |                         with transaction.commit_on_success_unless_managed(using=db): | ||||||
|                             try: |                             try: | ||||||
|                                 for sql in custom_sql: |                                 for sql in custom_sql: | ||||||
|                                     cursor.execute(sql) |                                     cursor.execute(sql) | ||||||
| @@ -130,9 +130,7 @@ class Command(NoArgsCommand): | |||||||
|                                                     (app_name, model._meta.object_name, e)) |                                                     (app_name, model._meta.object_name, e)) | ||||||
|                                 if show_traceback: |                                 if show_traceback: | ||||||
|                                     traceback.print_exc() |                                     traceback.print_exc() | ||||||
|                             transaction.rollback_unless_managed(using=db) |                                 raise | ||||||
|                         else: |  | ||||||
|                             transaction.commit_unless_managed(using=db) |  | ||||||
|                     else: |                     else: | ||||||
|                         if verbosity >= 3: |                         if verbosity >= 3: | ||||||
|                             self.stdout.write("No custom SQL for %s.%s model\n" % (app_name, model._meta.object_name)) |                             self.stdout.write("No custom SQL for %s.%s model\n" % (app_name, model._meta.object_name)) | ||||||
| @@ -147,15 +145,14 @@ class Command(NoArgsCommand): | |||||||
|                     if index_sql: |                     if index_sql: | ||||||
|                         if verbosity >= 2: |                         if verbosity >= 2: | ||||||
|                             self.stdout.write("Installing index for %s.%s model\n" % (app_name, model._meta.object_name)) |                             self.stdout.write("Installing index for %s.%s model\n" % (app_name, model._meta.object_name)) | ||||||
|  |                         with transaction.commit_on_success_unless_managed(using=db): | ||||||
|                             try: |                             try: | ||||||
|                                 for sql in index_sql: |                                 for sql in index_sql: | ||||||
|                                     cursor.execute(sql) |                                     cursor.execute(sql) | ||||||
|                             except Exception as e: |                             except Exception as e: | ||||||
|                                 self.stderr.write("Failed to install index for %s.%s model: %s\n" % \ |                                 self.stderr.write("Failed to install index for %s.%s model: %s\n" % \ | ||||||
|                                                     (app_name, model._meta.object_name, e)) |                                                     (app_name, model._meta.object_name, e)) | ||||||
|                             transaction.rollback_unless_managed(using=db) |                                 raise | ||||||
|                         else: |  | ||||||
|                             transaction.commit_unless_managed(using=db) |  | ||||||
|  |  | ||||||
|         # Load initial_data fixtures (unless that has been disabled) |         # Load initial_data fixtures (unless that has been disabled) | ||||||
|         if load_initial_data: |         if load_initial_data: | ||||||
|   | |||||||
| @@ -77,14 +77,3 @@ def close_old_connections(**kwargs): | |||||||
|         conn.close_if_unusable_or_obsolete() |         conn.close_if_unusable_or_obsolete() | ||||||
| signals.request_started.connect(close_old_connections) | signals.request_started.connect(close_old_connections) | ||||||
| signals.request_finished.connect(close_old_connections) | signals.request_finished.connect(close_old_connections) | ||||||
|  |  | ||||||
| # Register an event that rolls back the connections |  | ||||||
| # when a Django request has an exception. |  | ||||||
| def _rollback_on_exception(**kwargs): |  | ||||||
|     from django.db import transaction |  | ||||||
|     for conn in connections: |  | ||||||
|         try: |  | ||||||
|             transaction.rollback_unless_managed(using=conn) |  | ||||||
|         except DatabaseError: |  | ||||||
|             pass |  | ||||||
| signals.got_request_exception.connect(_rollback_on_exception) |  | ||||||
|   | |||||||
| @@ -339,27 +339,6 @@ class BaseDatabaseWrapper(object): | |||||||
|             return self.transaction_state[-1] |             return self.transaction_state[-1] | ||||||
|         return settings.TRANSACTIONS_MANAGED |         return settings.TRANSACTIONS_MANAGED | ||||||
|  |  | ||||||
|     def commit_unless_managed(self): |  | ||||||
|         """ |  | ||||||
|         Commits changes if the system is not in managed transaction mode. |  | ||||||
|         """ |  | ||||||
|         self.validate_thread_sharing() |  | ||||||
|         if not self.is_managed(): |  | ||||||
|             self.commit() |  | ||||||
|             self.clean_savepoints() |  | ||||||
|         else: |  | ||||||
|             self.set_dirty() |  | ||||||
|  |  | ||||||
|     def rollback_unless_managed(self): |  | ||||||
|         """ |  | ||||||
|         Rolls back changes if the system is not in managed transaction mode. |  | ||||||
|         """ |  | ||||||
|         self.validate_thread_sharing() |  | ||||||
|         if not self.is_managed(): |  | ||||||
|             self.rollback() |  | ||||||
|         else: |  | ||||||
|             self.set_dirty() |  | ||||||
|  |  | ||||||
|     ##### Foreign key constraints checks handling ##### |     ##### Foreign key constraints checks handling ##### | ||||||
|  |  | ||||||
|     @contextmanager |     @contextmanager | ||||||
|   | |||||||
| @@ -58,8 +58,6 @@ class DatabaseWrapper(BaseDatabaseWrapper): | |||||||
|     _set_autocommit = complain |     _set_autocommit = complain | ||||||
|     set_dirty = complain |     set_dirty = complain | ||||||
|     set_clean = complain |     set_clean = complain | ||||||
|     commit_unless_managed = complain |  | ||||||
|     rollback_unless_managed = ignore |  | ||||||
|  |  | ||||||
|     def __init__(self, *args, **kwargs): |     def __init__(self, *args, **kwargs): | ||||||
|         super(DatabaseWrapper, self).__init__(*args, **kwargs) |         super(DatabaseWrapper, self).__init__(*args, **kwargs) | ||||||
|   | |||||||
| @@ -609,6 +609,7 @@ class Model(six.with_metaclass(ModelBase)): | |||||||
|             if update_fields: |             if update_fields: | ||||||
|                 non_pks = [f for f in non_pks if f.name in update_fields or f.attname in update_fields] |                 non_pks = [f for f in non_pks if f.name in update_fields or f.attname in update_fields] | ||||||
|  |  | ||||||
|  |             with transaction.commit_on_success_unless_managed(using=using): | ||||||
|                 # First, try an UPDATE. If that doesn't update anything, do an INSERT. |                 # First, try an UPDATE. If that doesn't update anything, do an INSERT. | ||||||
|                 pk_val = self._get_pk_val(meta) |                 pk_val = self._get_pk_val(meta) | ||||||
|                 pk_set = pk_val is not None |                 pk_set = pk_val is not None | ||||||
| @@ -650,7 +651,6 @@ class Model(six.with_metaclass(ModelBase)): | |||||||
|  |  | ||||||
|                     if update_pk: |                     if update_pk: | ||||||
|                         setattr(self, meta.pk.attname, result) |                         setattr(self, meta.pk.attname, result) | ||||||
|             transaction.commit_unless_managed(using=using) |  | ||||||
|  |  | ||||||
|         # Store the database on which the object was saved |         # Store the database on which the object was saved | ||||||
|         self._state.db = using |         self._state.db = using | ||||||
| @@ -963,9 +963,9 @@ def method_set_order(ordered_obj, self, id_list, using=None): | |||||||
|     order_name = ordered_obj._meta.order_with_respect_to.name |     order_name = ordered_obj._meta.order_with_respect_to.name | ||||||
|     # FIXME: It would be nice if there was an "update many" version of update |     # FIXME: It would be nice if there was an "update many" version of update | ||||||
|     # for situations like this. |     # for situations like this. | ||||||
|  |     with transaction.commit_on_success_unless_managed(using=using): | ||||||
|         for i, j in enumerate(id_list): |         for i, j in enumerate(id_list): | ||||||
|             ordered_obj.objects.filter(**{'pk': j, order_name: rel_val}).update(_order=i) |             ordered_obj.objects.filter(**{'pk': j, order_name: rel_val}).update(_order=i) | ||||||
|     transaction.commit_unless_managed(using=using) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def method_get_order(ordered_obj, self): | def method_get_order(ordered_obj, self): | ||||||
|   | |||||||
| @@ -62,8 +62,6 @@ def force_managed(func): | |||||||
|             func(self, *args, **kwargs) |             func(self, *args, **kwargs) | ||||||
|             if forced_managed: |             if forced_managed: | ||||||
|                 transaction.commit(using=self.using) |                 transaction.commit(using=self.using) | ||||||
|             else: |  | ||||||
|                 transaction.commit_unless_managed(using=self.using) |  | ||||||
|         finally: |         finally: | ||||||
|             if forced_managed: |             if forced_managed: | ||||||
|                 transaction.leave_transaction_management(using=self.using) |                 transaction.leave_transaction_management(using=self.using) | ||||||
|   | |||||||
| @@ -460,8 +460,6 @@ class QuerySet(object): | |||||||
|                     self._batched_insert(objs_without_pk, fields, batch_size) |                     self._batched_insert(objs_without_pk, fields, batch_size) | ||||||
|             if forced_managed: |             if forced_managed: | ||||||
|                 transaction.commit(using=self.db) |                 transaction.commit(using=self.db) | ||||||
|             else: |  | ||||||
|                 transaction.commit_unless_managed(using=self.db) |  | ||||||
|         finally: |         finally: | ||||||
|             if forced_managed: |             if forced_managed: | ||||||
|                 transaction.leave_transaction_management(using=self.db) |                 transaction.leave_transaction_management(using=self.db) | ||||||
| @@ -590,8 +588,6 @@ class QuerySet(object): | |||||||
|             rows = query.get_compiler(self.db).execute_sql(None) |             rows = query.get_compiler(self.db).execute_sql(None) | ||||||
|             if forced_managed: |             if forced_managed: | ||||||
|                 transaction.commit(using=self.db) |                 transaction.commit(using=self.db) | ||||||
|             else: |  | ||||||
|                 transaction.commit_unless_managed(using=self.db) |  | ||||||
|         finally: |         finally: | ||||||
|             if forced_managed: |             if forced_managed: | ||||||
|                 transaction.leave_transaction_management(using=self.db) |                 transaction.leave_transaction_management(using=self.db) | ||||||
|   | |||||||
| @@ -123,16 +123,12 @@ def managed(flag=True, using=None): | |||||||
|         PendingDeprecationWarning, stacklevel=2) |         PendingDeprecationWarning, stacklevel=2) | ||||||
|  |  | ||||||
| def commit_unless_managed(using=None): | def commit_unless_managed(using=None): | ||||||
|     """ |     warnings.warn("'commit_unless_managed' is now a no-op.", | ||||||
|     Commits changes if the system is not in managed transaction mode. |         PendingDeprecationWarning, stacklevel=2) | ||||||
|     """ |  | ||||||
|     get_connection(using).commit_unless_managed() |  | ||||||
|  |  | ||||||
| def rollback_unless_managed(using=None): | def rollback_unless_managed(using=None): | ||||||
|     """ |     warnings.warn("'rollback_unless_managed' is now a no-op.", | ||||||
|     Rolls back changes if the system is not in managed transaction mode. |         PendingDeprecationWarning, stacklevel=2) | ||||||
|     """ |  | ||||||
|     get_connection(using).rollback_unless_managed() |  | ||||||
|  |  | ||||||
| ############### | ############### | ||||||
| # Public APIs # | # Public APIs # | ||||||
| @@ -280,3 +276,18 @@ def commit_manually(using=None): | |||||||
|         leave_transaction_management(using=using) |         leave_transaction_management(using=using) | ||||||
|  |  | ||||||
|     return _transaction_func(entering, exiting, using) |     return _transaction_func(entering, exiting, using) | ||||||
|  |  | ||||||
|  | def commit_on_success_unless_managed(using=None): | ||||||
|  |     """ | ||||||
|  |     Transitory API to preserve backwards-compatibility while refactoring. | ||||||
|  |     """ | ||||||
|  |     if is_managed(using): | ||||||
|  |         def entering(using): | ||||||
|  |             pass | ||||||
|  |  | ||||||
|  |         def exiting(exc_value, using): | ||||||
|  |             set_dirty(using=using) | ||||||
|  |  | ||||||
|  |         return _transaction_func(entering, exiting, using) | ||||||
|  |     else: | ||||||
|  |         return commit_on_success(using) | ||||||
|   | |||||||
| @@ -157,14 +157,6 @@ class DocTestRunner(doctest.DocTestRunner): | |||||||
|         doctest.DocTestRunner.__init__(self, *args, **kwargs) |         doctest.DocTestRunner.__init__(self, *args, **kwargs) | ||||||
|         self.optionflags = doctest.ELLIPSIS |         self.optionflags = doctest.ELLIPSIS | ||||||
|  |  | ||||||
|     def report_unexpected_exception(self, out, test, example, exc_info): |  | ||||||
|         doctest.DocTestRunner.report_unexpected_exception(self, out, test, |  | ||||||
|                                                           example, exc_info) |  | ||||||
|         # Rollback, in case of database errors. Otherwise they'd have |  | ||||||
|         # side effects on other tests. |  | ||||||
|         for conn in connections: |  | ||||||
|             transaction.rollback_unless_managed(using=conn) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class _AssertNumQueriesContext(CaptureQueriesContext): | class _AssertNumQueriesContext(CaptureQueriesContext): | ||||||
|     def __init__(self, test_case, num, connection): |     def __init__(self, test_case, num, connection): | ||||||
| @@ -490,14 +482,10 @@ class TransactionTestCase(SimpleTestCase): | |||||||
|                 conn.ops.sequence_reset_by_name_sql(no_style(), |                 conn.ops.sequence_reset_by_name_sql(no_style(), | ||||||
|                                                     conn.introspection.sequence_list()) |                                                     conn.introspection.sequence_list()) | ||||||
|             if sql_list: |             if sql_list: | ||||||
|                 try: |                 with transaction.commit_on_success_unless_managed(using=db_name): | ||||||
|                     cursor = conn.cursor() |                     cursor = conn.cursor() | ||||||
|                     for sql in sql_list: |                     for sql in sql_list: | ||||||
|                         cursor.execute(sql) |                         cursor.execute(sql) | ||||||
|                 except Exception: |  | ||||||
|                     transaction.rollback_unless_managed(using=db_name) |  | ||||||
|                     raise |  | ||||||
|                 transaction.commit_unless_managed(using=db_name) |  | ||||||
|  |  | ||||||
|     def _fixture_setup(self): |     def _fixture_setup(self): | ||||||
|         for db_name in self._databases_names(include_mirrors=False): |         for db_name in self._databases_names(include_mirrors=False): | ||||||
| @@ -537,11 +525,6 @@ class TransactionTestCase(SimpleTestCase): | |||||||
|             conn.close() |             conn.close() | ||||||
|  |  | ||||||
|     def _fixture_teardown(self): |     def _fixture_teardown(self): | ||||||
|         # Roll back any pending transactions in order to avoid a deadlock |  | ||||||
|         # during flush when TEST_MIRROR is used (#18984). |  | ||||||
|         for conn in connections.all(): |  | ||||||
|             conn.rollback_unless_managed() |  | ||||||
|  |  | ||||||
|         for db in self._databases_names(include_mirrors=False): |         for db in self._databases_names(include_mirrors=False): | ||||||
|             call_command('flush', verbosity=0, interactive=False, database=db, |             call_command('flush', verbosity=0, interactive=False, database=db, | ||||||
|                          skip_validation=True, reset_sequences=False) |                          skip_validation=True, reset_sequences=False) | ||||||
|   | |||||||
| @@ -352,6 +352,8 @@ these changes. | |||||||
|   - ``django.db.close_connection()`` |   - ``django.db.close_connection()`` | ||||||
|   - ``django.db.backends.creation.BaseDatabaseCreation.set_autocommit()`` |   - ``django.db.backends.creation.BaseDatabaseCreation.set_autocommit()`` | ||||||
|   - ``django.db.transaction.managed()`` |   - ``django.db.transaction.managed()`` | ||||||
|  |   - ``django.db.transaction.commit_unless_managed()`` | ||||||
|  |   - ``django.db.transaction.rollback_unless_managed()`` | ||||||
|  |  | ||||||
| 2.0 | 2.0 | ||||||
| --- | --- | ||||||
|   | |||||||
| @@ -208,38 +208,6 @@ class TestNewConnection(TransactionTestCase): | |||||||
|         connection.leave_transaction_management() |         connection.leave_transaction_management() | ||||||
|         self.assertEqual(orig_dirty, connection._dirty) |         self.assertEqual(orig_dirty, connection._dirty) | ||||||
|  |  | ||||||
|     # TODO: update this test to account for database-level autocommit. |  | ||||||
|     @expectedFailure |  | ||||||
|     def test_commit_unless_managed(self): |  | ||||||
|         cursor = connection.cursor() |  | ||||||
|         cursor.execute("INSERT into transactions_regress_mod (fld) values (2)") |  | ||||||
|         connection.commit_unless_managed() |  | ||||||
|         self.assertFalse(connection.is_dirty()) |  | ||||||
|         self.assertEqual(len(Mod.objects.all()), 1) |  | ||||||
|         self.assertTrue(connection.is_dirty()) |  | ||||||
|         connection.commit_unless_managed() |  | ||||||
|         self.assertFalse(connection.is_dirty()) |  | ||||||
|  |  | ||||||
|     # TODO: update this test to account for database-level autocommit. |  | ||||||
|     @expectedFailure |  | ||||||
|     def test_commit_unless_managed_in_managed(self): |  | ||||||
|         cursor = connection.cursor() |  | ||||||
|         connection.enter_transaction_management() |  | ||||||
|         cursor.execute("INSERT into transactions_regress_mod (fld) values (2)") |  | ||||||
|         connection.commit_unless_managed() |  | ||||||
|         self.assertTrue(connection.is_dirty()) |  | ||||||
|         connection.rollback() |  | ||||||
|         self.assertFalse(connection.is_dirty()) |  | ||||||
|         self.assertEqual(len(Mod.objects.all()), 0) |  | ||||||
|         connection.commit() |  | ||||||
|         connection.leave_transaction_management() |  | ||||||
|         self.assertFalse(connection.is_dirty()) |  | ||||||
|         self.assertEqual(len(Mod.objects.all()), 0) |  | ||||||
|         self.assertTrue(connection.is_dirty()) |  | ||||||
|         connection.commit_unless_managed() |  | ||||||
|         self.assertFalse(connection.is_dirty()) |  | ||||||
|         self.assertEqual(len(Mod.objects.all()), 0) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @skipUnless(connection.vendor == 'postgresql', | @skipUnless(connection.vendor == 'postgresql', | ||||||
|             "This test only valid for PostgreSQL") |             "This test only valid for PostgreSQL") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user