From: Kevin Benton Date: Wed, 13 Aug 2014 11:01:50 +0000 (-0700) Subject: BSN: Allow concurrent reads to consistency DB X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=b09c9950649c4c9fffa0b096eb21152cd84fe56f;p=openstack-build%2Fneutron-build.git BSN: Allow concurrent reads to consistency DB Allow concurrent reads to the consistency DB since the database lock the block was originally protecting against is gone. Closes-Bug: #1357102 Change-Id: I1618b4046e995c796757e723f99288e486683339 --- diff --git a/neutron/plugins/bigswitch/db/consistency_db.py b/neutron/plugins/bigswitch/db/consistency_db.py index 7f0faff0d..3a20c7dfe 100644 --- a/neutron/plugins/bigswitch/db/consistency_db.py +++ b/neutron/plugins/bigswitch/db/consistency_db.py @@ -14,7 +14,6 @@ # under the License. import sqlalchemy as sa -from neutron.common import exceptions from neutron.db import api as db from neutron.db import model_base from neutron.openstack.common import log as logging @@ -22,10 +21,6 @@ from neutron.openstack.common import log as logging LOG = logging.getLogger(__name__) -class MultipleReadForUpdateCalls(exceptions.NeutronException): - message = _("Only one read_for_update call may be made at a time.") - - class ConsistencyHash(model_base.BASEV2): ''' A simple table to store the latest consistency hash @@ -41,27 +36,23 @@ class ConsistencyHash(model_base.BASEV2): class HashHandler(object): ''' - A wrapper object to keep track of the session and hold the SQL - lock between the read and the update to prevent other servers - from reading the hash during a transaction. + A wrapper object to keep track of the session between the read + and the update operations. ''' def __init__(self, context=None, hash_id='1'): self.hash_id = hash_id self.session = db.get_session() if not context else context.session self.hash_db_obj = None - self.transaction = None def read_for_update(self): - if self.transaction: - raise MultipleReadForUpdateCalls() - self.transaction = self.session.begin(subtransactions=True) # REVISIT(kevinbenton): locking here with the DB is prone to deadlocks # in various multi-REST-call scenarios (router intfs, flips, etc). # Since it doesn't work in Galera deployments anyway, another sync # mechanism will have to be introduced to prevent inefficient double # syncs in HA deployments. - res = (self.session.query(ConsistencyHash). - filter_by(hash_id=self.hash_id).first()) + with self.session.begin(subtransactions=True): + res = (self.session.query(ConsistencyHash). + filter_by(hash_id=self.hash_id).first()) if not res: return '' self.hash_db_obj = res @@ -69,19 +60,11 @@ class HashHandler(object): def put_hash(self, hash): hash = hash or '' - if not self.transaction: - self.transaction = self.session.begin(subtransactions=True) - if self.hash_db_obj is not None: - self.hash_db_obj.hash = hash - else: - conhash = ConsistencyHash(hash_id=self.hash_id, hash=hash) - self.session.merge(conhash) - self.close_update_session() + with self.session.begin(subtransactions=True): + if self.hash_db_obj is not None: + self.hash_db_obj.hash = hash + else: + conhash = ConsistencyHash(hash_id=self.hash_id, hash=hash) + self.session.merge(conhash) LOG.debug(_("Consistency hash for group %(hash_id)s updated " "to %(hash)s"), {'hash_id': self.hash_id, 'hash': hash}) - - def close_update_session(self): - if not self.transaction: - return - self.transaction.commit() - self.transaction = None diff --git a/neutron/plugins/bigswitch/servermanager.py b/neutron/plugins/bigswitch/servermanager.py index 55eb05d31..941c8f2ca 100644 --- a/neutron/plugins/bigswitch/servermanager.py +++ b/neutron/plugins/bigswitch/servermanager.py @@ -197,8 +197,6 @@ class ServerProxy(object): except ValueError: # response was not JSON, ignore the exception pass - else: - hash_handler.close_update_session() ret = (response.status, response.reason, respstr, respdata) except httplib.HTTPException: # If we were using a cached connection, try again with a new one.