def __enter__(self): connection = transaction.get_connection(self.using) if not connection.in_atomic_block: # Reset state when entering an outermost atomic block. connection.commit_on_exit = True connection.needs_rollback = False if not connection.get_autocommit(): # Pretend we're already in an atomic block to bypass the code # that disables autocommit to enter a transaction, and make a # note to deal with this case in __exit__. connection.in_atomic_block = True connection.commit_on_exit = False if connection.in_atomic_block: # We're already in a transaction; create a savepoint, unless we # were told not to or we're already waiting for a rollback. The # second condition avoids creating useless savepoints and prevents # overwriting needs_rollback until the rollback is performed. if self.savepoint and not connection.needs_rollback: sid = connection.savepoint() connection.savepoint_ids.append(sid) else: connection.savepoint_ids.append(None) else: if self.immediate: connection.set_autocommit(False) connection.cursor().execute('BEGIN IMMEDIATE') else: connection.set_autocommit( False, force_begin_transaction_with_broken_autocommit=True) connection.in_atomic_block = True
def test_raises_exception_non_autocommit_mode(self): def should_never_be_called(): raise AssertionError('this function should never be called') try: connection.set_autocommit(False) with self.assertRaises(transaction.TransactionManagementError): transaction.on_commit(should_never_be_called) finally: connection.set_autocommit(True)
def test_raises_exception_non_autocommit_mode(self): def should_never_be_called(): raise AssertionError('this function should never be called') try: connection.set_autocommit(False) msg = 'on_commit() cannot be used in manual transaction management' with self.assertRaisesMessage(transaction.TransactionManagementError, msg): transaction.on_commit(should_never_be_called) finally: connection.set_autocommit(True)
def test_commit(self): """ Users are allowed to commit and rollback connections. """ connection.set_autocommit(False) try: # The starting value is False, not None. self.assertIs(connection._dirty, False) list(Mod.objects.all()) self.assertTrue(connection.is_dirty()) connection.commit() self.assertFalse(connection.is_dirty()) list(Mod.objects.all()) self.assertTrue(connection.is_dirty()) connection.rollback() self.assertFalse(connection.is_dirty()) finally: connection.set_autocommit(True)
def test_set_autocommit_health_checks_enabled(self): self.patch_settings_dict(conn_health_checks=True) self.assertIsNone(connection.connection) # Newly created connections are considered healthy without performing # the health check. with patch.object(connection, "is_usable", side_effect=AssertionError): # Simulate outermost atomic block: changing autocommit for # a connection. connection.set_autocommit(False) self.run_query() connection.commit() connection.set_autocommit(True) old_connection = connection.connection # Simulate request_finished. connection.close_if_unusable_or_obsolete() # Persistent connections are enabled. self.assertIs(old_connection, connection.connection) # Simulate connection health check failing. with patch.object( connection, "is_usable", return_value=False ) as mocked_is_usable: # Simulate outermost atomic block: changing autocommit for # a connection. connection.set_autocommit(False) new_connection = connection.connection self.assertIsNot(new_connection, old_connection) # Only one health check per "request" is performed, so a query will # carry on even if the health check fails. This query succeeds # because the real connection is healthy and only the health check # failure is mocked. self.run_query() connection.commit() connection.set_autocommit(True) # The connection is unchanged. self.assertIs(new_connection, connection.connection) self.assertEqual(mocked_is_usable.call_count, 1) # Simulate request_finished. connection.close_if_unusable_or_obsolete() # The underlying connection is being reused further with health checks # succeeding. connection.set_autocommit(False) self.run_query() connection.commit() connection.set_autocommit(True) self.assertIs(new_connection, connection.connection)
def setUpClass(cls): super(CubaneManualTransactionTestCase, cls).setUpClass() connection.set_autocommit(False)
def forwards(self, orm): # On SQLite, database transactions (which are used by # `Document.objects.sync`) requires autocommit to be turned on. South # however doesn't enable this by default. if connection.vendor == 'sqlite': autocommit = connection.get_autocommit() connection.set_autocommit(True) # Adding model 'Document' if 'desktop_document' not in connection.introspection.table_names(): db.create_table('desktop_document', ( ('description', self.gf('django.db.models.fields.TextField')(default='')), ('extra', self.gf('django.db.models.fields.TextField')(default='')), ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()), ('last_modified', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, db_index=True, blank=True)), ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])), ('version', self.gf('django.db.models.fields.SmallIntegerField')(default=1)), ('owner', self.gf('django.db.models.fields.related.ForeignKey')(related_name='doc_owner', to=orm['auth.User'])), ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('name', self.gf('django.db.models.fields.TextField')(default='')), )) db.send_create_signal('desktop', ['Document']) # Adding model 'DocumentPermission' if 'desktop_documentpermission' not in connection.introspection.table_names(): db.create_table('desktop_documentpermission', ( ('perms', self.gf('django.db.models.fields.TextField')(default='read')), ('doc', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['desktop.Document'])), ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), )) db.send_create_signal('desktop', ['DocumentPermission']) # Adding M2M table for field users on 'DocumentPermission' if 'documentpermission_users' not in connection.introspection.table_names(): db.create_table('documentpermission_users', ( ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), ('documentpermission', models.ForeignKey(orm['desktop.documentpermission'], null=False)), ('user', models.ForeignKey(orm['auth.user'], null=False)) )) db.create_unique('documentpermission_users', ['documentpermission_id', 'user_id']) # Adding M2M table for field groups on 'DocumentPermission' if 'documentpermission_groups' not in connection.introspection.table_names(): db.create_table('documentpermission_groups', ( ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), ('documentpermission', models.ForeignKey(orm['desktop.documentpermission'], null=False)), ('group', models.ForeignKey(orm['auth.group'], null=False)) )) db.create_unique('documentpermission_groups', ['documentpermission_id', 'group_id']) # Adding model 'DocumentTag' if 'desktop_documenttag' not in connection.introspection.table_names(): db.create_table('desktop_documenttag', ( ('owner', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), ('tag', self.gf('django.db.models.fields.SlugField')(max_length=50, db_index=True)), ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), )) db.send_create_signal('desktop', ['DocumentTag']) # Adding M2M table for field tags on 'Document' if 'desktop_document_tags' not in connection.introspection.table_names(): db.create_table('desktop_document_tags', ( ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), ('document', models.ForeignKey(orm['desktop.document'], null=False)), ('documenttag', models.ForeignKey(orm['desktop.documenttag'], null=False)) )) db.create_unique('desktop_document_tags', ['document_id', 'documenttag_id']) if not db.dry_run: Document.objects.sync() if connection.vendor == 'sqlite': connection.set_autocommit(autocommit)
def testAutocommit(self): from django.db import connection connection.set_autocommit(False) self.connect_mock.query.assert_called_with('SET SESSION AUTOCOMMIT TO OFF') connection.set_autocommit(True) self.connect_mock.query.assert_called_with('SET SESSION AUTOCOMMIT TO ON')