diff --git a/neutron/db/api.py b/neutron/db/api.py index 3a2752ae1bc..0b68bd3310a 100644 --- a/neutron/db/api.py +++ b/neutron/db/api.py @@ -14,10 +14,13 @@ # under the License. import contextlib +import six from oslo_config import cfg +from oslo_db import exception as os_db_exception from oslo_db.sqlalchemy import session from sqlalchemy import exc +from sqlalchemy import orm _FACADE = None @@ -64,3 +67,21 @@ def autonested_transaction(sess): finally: with session_context as tx: yield tx + + +class convert_db_exception_to_retry(object): + """Converts other types of DB exceptions into RetryRequests.""" + + def __init__(self, stale_data=False): + self.to_catch = () + if stale_data: + self.to_catch += (orm.exc.StaleDataError, ) + + def __call__(self, f): + @six.wraps(f) + def wrapper(*args, **kwargs): + try: + return f(*args, **kwargs) + except self.to_catch as e: + raise os_db_exception.RetryRequest(e) + return wrapper diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 2cf2ec80f45..00cd60a476d 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -1376,7 +1376,9 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, return self._bind_port_if_needed(port_context) @oslo_db_api.wrap_db_retry(max_retries=db_api.MAX_RETRIES, - retry_on_deadlock=True) + retry_on_deadlock=True, + retry_on_request=True) + @db_api.convert_db_exception_to_retry(stale_data=True) def update_port_status(self, context, port_id, status, host=None, network=None): """