Exemple #1
0
    def _wrap(self, *args, **kwargs):
        try:
            assert issubclass(
                self.__class__, sqlalchemy.orm.session.Session), (
                    '_wrap_db_error() can only be applied to methods of '
                    'subclasses of sqlalchemy.orm.session.Session.')

            return f(self, *args, **kwargs)
        except UnicodeEncodeError:
            raise exception.DBInvalidUnicodeParameter()
        except sqla_exc.OperationalError as e:
            _raise_if_db_connection_lost(e, self.bind)
            _raise_if_deadlock_error(e, self.bind.dialect.name)
            # NOTE(comstud): A lot of code is checking for OperationalError
            # so let's not wrap it for now.
            raise
        # note(boris-42): We should catch unique constraint violation and
        # wrap it by our own DBDuplicateEntry exception. Unique constraint
        # violation is wrapped by IntegrityError.
        except sqla_exc.IntegrityError as e:
            # note(boris-42): SqlAlchemy doesn't unify errors from different
            # DBs so we must do this. Also in some tables (for example
            # instance_types) there are more than one unique constraint. This
            # means we should get names of columns, which values violate
            # unique constraint, from error message.
            _raise_if_duplicate_entry_error(e, self.bind.dialect.name)
            raise exception.DBError(e)
        except Exception as e:
            LOG.exception(_LE('DB exception wrapped.'))
            raise exception.DBError(e)
Exemple #2
0
 def _wrap(*args, **kwargs):
     try:
         return f(*args, **kwargs)
     except UnicodeEncodeError:
         raise exception.DBInvalidUnicodeParameter()
     # note(boris-42): We should catch unique constraint violation and
     # wrap it by our own DBDuplicateEntry exception. Unique constraint
     # violation is wrapped by IntegrityError.
     except sqla_exc.OperationalError, e:
         raise_if_deadlock_error(e, get_engine().name)
         # NOTE(comstud): A lot of code is checking for OperationalError
         # so let's not wrap it for now.
         raise
Exemple #3
0
 def _wrap(*args, **kwargs):
     try:
         return f(*args, **kwargs)
     except UnicodeEncodeError:
         raise exception.DBInvalidUnicodeParameter()
     # note(boris-42): We should catch unique constraint violation and
     # wrap it by our own DBDuplicateEntry exception. Unique constraint
     # violation is wrapped by IntegrityError.
     except sqla_exc.OperationalError as e:
         _raise_if_deadlock_error(e, get_engine().name)
         # NOTE(comstud): A lot of code is checking for OperationalError
         # so let's not wrap it for now.
         raise
     except sqla_exc.IntegrityError as e:
         # note(boris-42): SqlAlchemy doesn't unify errors from different
         # DBs so we must do this. Also in some tables (for example
         # instance_types) there are more than one unique constraint. This
         # means we should get names of columns, which values violate
         # unique constraint, from error message.
         _raise_if_duplicate_entry_error(e, get_engine().name)
         raise exception.DBError(e)
     except Exception as e:
         LOG.exception(_('DB exception wrapped.'))
         raise exception.DBError(e)
Exemple #4
0
    def _wrap(*args, **kwargs):
        if get_engine().dialect.dbapi.__name__ == 'MySQLdb':
            import MySQLdb
            operational_errors = (MySQLdb.OperationalError,
                                  sqla_exc.OperationalError)
        else:
            operational_errors = (sqla_exc.OperationalError, )

        next_interval = CONF.sql_retry_interval
        remaining = CONF.sql_max_retries
        if remaining == -1:
            remaining = 'infinite'
        while True:
            try:
                return f(*args, **kwargs)
            except UnicodeEncodeError:
                raise exception.DBInvalidUnicodeParameter()
            # note(boris-42): We should catch unique constraint violation and
            # wrap it by our own DBDuplicateEntry exception. Unique constraint
            # violation is wrapped by IntegrityError.
            except operational_errors as e:
                raise_if_deadlock_error(e, get_engine().name)
                if is_db_connection_error(e.args[0]):
                    if remaining == 0:
                        LOG.exception(_('DB exceeded retry limit.'))
                        raise DBError(e)
                    if remaining != 'infinite':
                        remaining -= 1
                    LOG.exception(
                        _('DB connection error, '
                          'retrying in %i seconds.') % next_interval)
                    time.sleep(next_interval)
                    if CONF.sql_inc_retry_interval:
                        next_interval = min(next_interval * 2,
                                            CONF.sql_max_retry_interval)
                else:
                    LOG.exception(_('DB exception wrapped.'))
                    raise exception.DBError(e)
            except sqla_exc.IntegrityError, e:
                # note(boris-42): SqlAlchemy doesn't unify errors from different
                # DBs so we must do this. Also in some tables (for example
                # instance_types) there are more than one unique constraint. This
                # means we should get names of columns, which values violate
                # unique constraint, from error message.
                raise_if_duplicate_entry_error(e, get_engine().name)
                raise exception.DBError(e)
            except sqla_exc.InvalidRequestError as e:
                exc_re = re.search(
                    '(.*)Original\s+exception\s+was:'
                    '\s+\((.*)\)\s+\((.*)\)', e.args[0])
                if exc_re:
                    invalidreqerror_msg = exc_re.group(1)
                    original_exception_type = exc_re.group(2)
                    original_exception_value = exc_re.group(3)
                    if re.search('rollback', invalidreqerror_msg):
                        get_session().rollback()
                    if is_db_connection_error(original_exception_value):
                        if remaining == 0:
                            LOG.exception(_('DB exceeded retry limit.'))
                            raise DBError(e)
                        if remaining != 'infinite':
                            remaining -= 1
                        LOG.exception(
                            _('DB connection error, '
                              'retrying in %i seconds.') % next_interval)
                        time.sleep(next_interval)
                        if CONF.sql_inc_retry_interval:
                            next_interval = min(next_interval * 2,
                                                CONF.sql_max_retry_interval)
                    else:
                        LOG.exception(_('DB exception wrapped.'))
                        raise exception.DBError(e)
                else:
                    LOG.exception(_('DB exception wrapped.'))
                    raise exception.DBError(e)