Ticket #11156: 11156.diff

File 11156.diff, 7.0 KB (added by Ian Kelly, 10 years ago)
  • django/db/models/query.py

     
    364364                params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
    365365                params.update(defaults)
    366366                obj = self.model(**params)
    367                 sid = transaction.savepoint(using=self.db)
     367                sid = transaction.savepoint(using=self.db, only_if_needed=True)
    368368                obj.save(force_insert=True, using=self.db)
    369                 transaction.savepoint_commit(sid, using=self.db)
     369                transaction.savepoint_commit(sid, using=self.db,
     370                                             only_if_needed=True)
    370371                return obj, True
    371372            except IntegrityError, e:
    372                 transaction.savepoint_rollback(sid, using=self.db)
     373                transaction.savepoint_rollback(sid, using=self.db,
     374                                               only_if_needed=True)
    373375                try:
    374376                    return self.get(**kwargs), False
    375377                except self.model.DoesNotExist:
  • django/db/backends/postgresql/base.py

     
    6767
    6868class DatabaseFeatures(BaseDatabaseFeatures):
    6969    uses_savepoints = True
     70    needs_savepoint_on_exception = True
    7071
    7172class DatabaseWrapper(BaseDatabaseWrapper):
    7273    operators = {
  • django/db/backends/__init__.py

     
    5050        """
    5151        pass
    5252
    53     def _savepoint(self, sid):
     53    def _savepoint(self, sid, only_if_needed=False):
    5454        if not self.features.uses_savepoints:
    5555            return
     56        if only_if_needed and not self.features.needs_savepoint_on_exception:
     57            return
    5658        self.cursor().execute(self.ops.savepoint_create_sql(sid))
    5759
    58     def _savepoint_rollback(self, sid):
     60    def _savepoint_rollback(self, sid, only_if_needed=False):
    5961        if not self.features.uses_savepoints:
    6062            return
     63        if only_if_needed and not self.features.needs_savepoint_on_exception:
     64            return
    6165        self.cursor().execute(self.ops.savepoint_rollback_sql(sid))
    6266
    63     def _savepoint_commit(self, sid):
     67    def _savepoint_commit(self, sid, only_if_needed=False):
    6468        if not self.features.uses_savepoints:
    6569            return
     70        if only_if_needed and not self.features.needs_savepoint_on_exception:
     71            return
    6672        self.cursor().execute(self.ops.savepoint_commit_sql(sid))
    6773
    6874    def close(self):
     
    9298    can_return_id_from_insert = False
    9399    uses_autocommit = False
    94100    uses_savepoints = False
     101    needs_savepoint_on_exception = False
    95102    # If True, don't use integer foreign keys referring to, e.g., positive
    96103    # integer primary keys.
    97104    related_fields_match_type = False
  • django/db/backends/postgresql_psycopg2/base.py

     
    3030class DatabaseFeatures(BaseDatabaseFeatures):
    3131    needs_datetime_string_cast = False
    3232    can_return_id_from_insert = False
     33    uses_savepoints = True
    3334
    3435class DatabaseOperations(PostgresqlDatabaseOperations):
    3536    def last_executed_query(self, cursor, sql, params):
     
    148149                self.connection.set_isolation_level(level)
    149150        finally:
    150151            self.isolation_level = level
    151             self.features.uses_savepoints = bool(level)
     152            self.features.needs_savepoint_on_exception = bool(level)
  • django/db/transaction.py

     
    209209    connection._rollback()
    210210    set_clean(using=using)
    211211
    212 def savepoint(using=None):
     212def savepoint(using=None, only_if_needed=False):
    213213    """
    214214    Creates a savepoint (if supported and required by the backend) inside the
    215215    current transaction. Returns an identifier for the savepoint that will be
     
    226226        savepoint_state[thread_ident][using] = [None]
    227227    tid = str(thread_ident).replace('-', '')
    228228    sid = "s%s_x%d" % (tid, len(savepoint_state[thread_ident][using]))
    229     connection._savepoint(sid)
     229    connection._savepoint(sid, only_if_needed)
    230230    return sid
    231231
    232 def savepoint_rollback(sid, using=None):
     232def savepoint_rollback(sid, using=None, only_if_needed=False):
    233233    """
    234234    Rolls back the most recent savepoint (if one exists). Does nothing if
    235     savepoints are not supported.
     235    savepoints are not supported, or if only_if_needed is set and the backend
     236    does not need to use savepoints to recover from exceptions.
    236237    """
    237238    if using is None:
    238239        using = DEFAULT_DB_ALIAS
    239240    connection = connections[using]
    240241    thread_ident = thread.get_ident()
    241242    if thread_ident in savepoint_state and using in savepoint_state[thread_ident]:
    242         connection._savepoint_rollback(sid)
     243        connection._savepoint_rollback(sid, only_if_needed)
    243244
    244 def savepoint_commit(sid, using=None):
     245def savepoint_commit(sid, using=None, only_if_needed=False):
    245246    """
    246247    Commits the most recent savepoint (if one exists). Does nothing if
    247     savepoints are not supported.
     248    savepoints are not supported, or if only_if_needed is set and the backend
     249    does not need to use savepoints to recover from exceptions.
    248250    """
    249251    if using is None:
    250252        using = DEFAULT_DB_ALIAS
    251253    connection = connections[using]
    252254    thread_ident = thread.get_ident()
    253255    if thread_ident in savepoint_state and using in savepoint_state[thread_ident]:
    254         connection._savepoint_commit(sid)
     256        connection._savepoint_commit(sid, only_if_needed)
    255257
    256258##############
    257259# DECORATORS #
  • django/contrib/sessions/backends/db.py

     
    5858            session_data = self.encode(self._get_session(no_load=must_create)),
    5959            expire_date = self.get_expiry_date()
    6060        )
    61         sid = transaction.savepoint(using=self.using)
     61        sid = transaction.savepoint(using=self.using, only_if_needed=True)
    6262        try:
    6363            obj.save(force_insert=must_create)
    6464        except IntegrityError:
    6565            if must_create:
    66                 transaction.savepoint_rollback(sid, using=self.using)
     66                transaction.savepoint_rollback(sid, using=self.using,
     67                                               only_if_needed=True)
    6768                raise CreateError
    6869            raise
    6970
Back to Top