Ticket #3460: 3640_r9736-autocommit-safe.diff
File 3640_r9736-autocommit-safe.diff, 8.0 KB (added by , 16 years ago) |
---|
-
django/db/models/sql/subqueries.py
304 304 result = ['INSERT INTO %s' % qn(self.model._meta.db_table)] 305 305 result.append('(%s)' % ', '.join([qn(c) for c in self.columns])) 306 306 result.append('VALUES (%s)' % ', '.join(self.values)) 307 if self.connection.features.can_return_id_from_insert: 308 result.append('RETURNING %s.%s' % (qn(self.model._meta.db_table), 309 qn(self.model._meta.pk.column))) 310 307 311 return ' '.join(result), self.params 308 312 309 313 def execute_sql(self, return_id=False): 310 314 cursor = super(InsertQuery, self).execute_sql(None) 311 if return_id: 315 if return_id and self.connection.features.can_return_id_from_insert: 316 row_id = cursor.fetchone()[0] 317 return row_id 318 elif return_id: 312 319 return self.connection.ops.last_insert_id(cursor, 313 320 self.model._meta.db_table, self.model._meta.pk.column) 314 321 -
django/db/backends/__init__.py
31 31 if self.connection is not None: 32 32 return self.connection.rollback() 33 33 34 def _enter_transaction_management(self, managed): 35 pass 36 37 def _leave_transaction_management(self, managed): 38 pass 39 34 40 def _savepoint(self, sid): 35 41 if not self.features.uses_savepoints: 36 42 return … … 74 80 # If True, don't use integer foreign keys referring to, e.g., positive 75 81 # integer primary keys. 76 82 related_fields_match_type = False 83 native_autocommit = False 84 can_return_id_from_insert = False 77 85 78 86 class BaseDatabaseOperations(object): 79 87 """ -
django/db/backends/postgresql_psycopg2/base.py
4 4 Requires psycopg 2: http://initd.org/projects/psycopg2 5 5 """ 6 6 7 from django.conf import settings 7 8 from django.db.backends import * 8 9 from django.db.backends.postgresql.operations import DatabaseOperations as PostgresqlDatabaseOperations 9 10 from django.db.backends.postgresql.client import DatabaseClient … … 28 29 29 30 class DatabaseFeatures(BaseDatabaseFeatures): 30 31 needs_datetime_string_cast = False 31 uses_savepoints = True32 32 33 33 class DatabaseOperations(PostgresqlDatabaseOperations): 34 34 def last_executed_query(self, cursor, sql, params): … … 59 59 super(DatabaseWrapper, self).__init__(*args, **kwargs) 60 60 61 61 self.features = DatabaseFeatures() 62 if settings.DATABASE_OPTIONS.get('native_autocommit', False): 63 self.features.native_autocommit = True 64 self.features.uses_savepoints = False 65 self.features.can_return_id_from_insert = True 66 self._isolation_level = 0 67 else: 68 self.features.native_autocommit = False 69 self.features.uses_savepoints = True 70 self.features.can_return_id_from_insert = False 71 self._isolation_level = 1 62 72 self.ops = DatabaseOperations() 63 73 self.client = DatabaseClient() 64 74 self.creation = DatabaseCreation(self) 65 75 self.introspection = DatabaseIntrospection(self) 66 76 self.validation = BaseDatabaseValidation() 77 78 def _enter_transaction_management(self, managed): 79 """Manages the mapping of transaction management to isolation levels""" 67 80 81 if self.features.native_autocommit and managed and self._isolation_level == 0: 82 try: 83 if self.connection != None: 84 self.connection.set_isolation_level(1) 85 finally: 86 self._isolation_level = 1 87 self.features.uses_savepoints = True 88 89 def _leave_transaction_management(self, managed): 90 """Manages the mapping of transaction management to isolation levels""" 91 92 if self.features.native_autocommit and not managed and self._isolation_level == 1: 93 try: 94 if self.connection != None: 95 self.connection.set_isolation_level(0) 96 finally: 97 self._isolation_level = 0 98 self.features.uses_savepoints = False 99 68 100 def _cursor(self, settings): 69 101 set_tz = False 70 102 if self.connection is None: … … 81 113 conn_string += " host=%s" % settings.DATABASE_HOST 82 114 if settings.DATABASE_PORT: 83 115 conn_string += " port=%s" % settings.DATABASE_PORT 84 self.connection = Database.connect(conn_string, **self.options) 85 self.connection.set_isolation_level(1) # make transactions transparent to all cursors 116 x = self.options.copy() 117 x.pop('native_autocommit', '') 118 self.connection = Database.connect(conn_string, **x) 119 self.connection.set_isolation_level(self._isolation_level) 86 120 self.connection.set_client_encoding('UTF8') 87 121 cursor = self.connection.cursor() 88 122 cursor.tzinfo_factory = None -
django/db/transaction.py
40 40 # database commit. 41 41 dirty = {} 42 42 43 def enter_transaction_management( ):43 def enter_transaction_management(managed=True): 44 44 """ 45 45 Enters transaction management for a running thread. It must be balanced with 46 46 the appropriate leave_transaction_management call, since the actual state is … … 58 58 state[thread_ident].append(settings.TRANSACTIONS_MANAGED) 59 59 if thread_ident not in dirty: 60 60 dirty[thread_ident] = False 61 connection._enter_transaction_management(managed) 61 62 62 63 def leave_transaction_management(): 63 64 """ … … 65 66 over to the surrounding block, as a commit will commit all changes, even 66 67 those from outside. (Commits are on connection level.) 67 68 """ 69 connection._leave_transaction_management(is_managed()) 68 70 thread_ident = thread.get_ident() 69 71 if thread_ident in state and state[thread_ident]: 70 72 del state[thread_ident][-1] … … 216 218 """ 217 219 def _autocommit(*args, **kw): 218 220 try: 219 enter_transaction_management( )221 enter_transaction_management(managed=False) 220 222 managed(False) 221 223 return func(*args, **kw) 222 224 finally: -
docs/ref/databases.txt
260 260 column types have a maximum length restriction of 255 characters, regardless 261 261 of whether ``unique=True`` is specified or not. 262 262 263 .. _postgresql-notes: 264 265 PostgreSQL notes 266 ================ 267 268 Django supports PostgreSQL using the psycopg_ package. Django supports both 269 version 1 and 2. (When you configure Django's database layer, specify either 270 ``postgresql`` [for version 1] or ``postgresql_psycopg2`` [for version 2].) 271 272 Native Autocommit 273 ----------------- 274 275 By default, Django database backends run with a permanently open 276 transaction, as per the Python DB-API. Django simulates autocommit behaviour 277 by committing this transaction automatically (e.g. in ``save()``). For 278 PostgreSQL, this corresponds to running in ``set_isolation_level(1)``. 279 280 For higher performance, ``postgresql_psycopg2`` can be configured to run 281 without an open connection when Django is in autocommit mode. This 282 corresponds to PostgreSQL ``set_isolation_level(0)`` and is configured 283 with:: 284 285 DATABASE_OPTIONS = {'native_autocommit':True} 286 287 .. _psycopg: http://initd.org/pub/software/psycopg/ 288 263 289 .. _sqlite-notes: 264 290 265 291 SQLite notes