From 85b70a9c182106ff0707acbd79e2d502a130fe3d Mon Sep 17 00:00:00 2001 From: Manjeet Singh Bhatia Date: Mon, 6 Mar 2017 21:39:30 +0000 Subject: [PATCH] Make query in quota api lockless As one of query to fetch quota usage by resource and tenant was done in lock mode earlier. This was done to protect the dirty bit in the usage which tracks for update. For moving to OVO carrying lock mode can be avoided by making sure that dirty attribute of quotausages is still protected. Change-Id: I0bb9f6fb7be51be590afb527a56e0569e922e98f Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db --- neutron/db/quota/api.py | 9 ++++----- neutron/quota/resource.py | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/neutron/db/quota/api.py b/neutron/db/quota/api.py index 95034e8ffa1..646d297bc6a 100644 --- a/neutron/db/quota/api.py +++ b/neutron/db/quota/api.py @@ -41,22 +41,21 @@ class ReservationInfo(collections.namedtuple( @db_api.retry_if_session_inactive() -def get_quota_usage_by_resource_and_tenant(context, resource, tenant_id, - lock_for_update=False): +def get_quota_usage_by_resource_and_tenant(context, resource, tenant_id): """Return usage info for a given resource and tenant. :param context: Request context :param resource: Name of the resource :param tenant_id: Tenant identifier - :param lock_for_update: if True sets a write-intent lock on the query :returns: a QuotaUsageInfo instance """ query = db_utils.model_query(context, quota_models.QuotaUsage) query = query.filter_by(resource=resource, tenant_id=tenant_id) - if lock_for_update: - query = query.with_lockmode('update') + # NOTE(manjeets) as lock mode was just for protecting dirty bits + # an update on dirty will prevent the race. + query.filter_by(dirty=True).update({'dirty': True}) result = query.first() if not result: diff --git a/neutron/quota/resource.py b/neutron/quota/resource.py index 2623d6e0adb..ab97bb3e8ef 100644 --- a/neutron/quota/resource.py +++ b/neutron/quota/resource.py @@ -250,7 +250,7 @@ class TrackedResource(BaseResource): """ # Load current usage data, setting a row-level lock on the DB usage_info = quota_api.get_quota_usage_by_resource_and_tenant( - context, self.name, tenant_id, lock_for_update=True) + context, self.name, tenant_id) # Always fetch reservations, as they are not tracked by usage counters reservations = quota_api.get_reservations_for_resources( context, tenant_id, [self.name])