Add _wrap_db_error() support to Session.commit()
This patch adds _wrap_db_error() to session.commit(), which has been observed to be a common point of failure for deadlock exceptions. In order to achieve this, the _wrap_db_error() decorator itself also needed to propagate an existing DBError, as it is the case that SQLAlchemy's session.commit() calls into the session.flush() method. Tests are added to exercise both the nesting of _wrap_db_error() when a flush() inside commit() raises an exception, as well as when commit() alone raises an exception that the error is wrapped as expected. Tests are omitted here as we are relying upon the tests that were added to the corresponding oslo-incubator code. Closes-bug: #1370191 Change-Id: I91510a2b864f0c1b73cfae18f271e94334714dce
This commit is contained in:
parent
b5958c7450
commit
3371ad81ba
|
@ -455,6 +455,10 @@ def _wrap_db_error(f):
|
|||
# unique constraint, from error message.
|
||||
_raise_if_duplicate_entry_error(e, self.bind.dialect.name)
|
||||
raise exception.DBError(e)
|
||||
except exception.DBError:
|
||||
# note(zzzeek) - if _wrap_db_error is applied to nested functions,
|
||||
# ensure an existing DBError is propagated outwards
|
||||
raise
|
||||
except Exception as e:
|
||||
LOG.exception(_LE('DB exception wrapped.'))
|
||||
raise exception.DBError(e)
|
||||
|
@ -692,6 +696,10 @@ class Session(sqlalchemy.orm.session.Session):
|
|||
def execute(self, *args, **kwargs):
|
||||
return super(Session, self).execute(*args, **kwargs)
|
||||
|
||||
@_wrap_db_error
|
||||
def commit(self, *args, **kwargs):
|
||||
return super(Session, self).commit(*args, **kwargs)
|
||||
|
||||
|
||||
def get_maker(engine, autocommit=True, expire_on_commit=False):
|
||||
"""Return a SQLAlchemy sessionmaker using the given engine."""
|
||||
|
|
Loading…
Reference in New Issue