Пример #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)
Пример #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 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)
Пример #3
0
        def wrapper(*args, **kwargs):
            next_interval = self.retry_interval
            remaining = self.max_retries

            while True:
                try:
                    return f(*args, **kwargs)
                except exception.DBConnectionError as e:
                    if remaining == 0:
                        LOG.exception(_LE('DB exceeded retry limit.'))
                        raise exception.DBError(e)
                    if remaining != -1:
                        remaining -= 1
                        LOG.exception(_LE('DB connection error.'))
                    # NOTE(vsergeyev): We are using patched time module, so
                    #                  this effectively yields the execution
                    #                  context to another green thread.
                    time.sleep(next_interval)
                    if self.inc_retry_interval:
                        next_interval = min(next_interval * 2,
                                            self.max_retry_interval)
Пример #4
0
        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
        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 Exception, e:
            LOG.exception(_('DB exception wrapped.'))
            raise exception.DBError(e)
    _wrap.func_name = f.func_name
    return _wrap


def get_engine():
    """Return a SQLAlchemy engine."""
    global _ENGINE
    if _ENGINE is None:
        _ENGINE = create_engine(CONF.sql_connection)
    return _ENGINE


def synchronous_switch_listener(dbapi_conn, connection_rec):
    """Switch sqlite connections to non-synchronous mode."""
    dbapi_conn.execute("PRAGMA synchronous = OFF")
Пример #5
0
 def __init__(self):
     self._cell_data_sync = mock.Mock()
     self._cell_data_sync.side_effect = [db_exc.DBError(), []]
     super(TestCellStateManagerDB, self).__init__()
Пример #6
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)