From f8f50397ca1e4ab7f5f31b19dde255ab70b4ccaf Mon Sep 17 00:00:00 2001 From: Slawek Kaplonski Date: Wed, 15 Sep 2021 15:47:35 +0200 Subject: [PATCH] Rollback db session in case of error during releasing quota reservation Patch [1] changed to not fail if DBError will happend when releasing quota reservation. That may lead to the errors while commiting db transaction in the neutron/api/v2/base.py module when in same transaction Neutron commits reservation (which removes reservation from db) and then set resources dirty. In case if DB error happens in the commit_reservation() and we will simply pass this error and move on, transaction can't be commited without rollback. This patch adds handle of such DBErrors in the remove_reservation function so transaction can be rolled back in case of DB error happens. [1] https://review.opendev.org/c/openstack/neutron/+/805031 Closes-Bug: #1943714 Change-Id: I295a4f0eb1eaf0286f0e34b96db29c8f08340b84 --- neutron/db/quota/api.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/neutron/db/quota/api.py b/neutron/db/quota/api.py index c99ebb9a861..121e19a1ca2 100644 --- a/neutron/db/quota/api.py +++ b/neutron/db/quota/api.py @@ -19,7 +19,6 @@ import datetime from neutron_lib.db import api as db_api from oslo_db import exception as db_exc -from neutron.common import utils from neutron.objects import quota as quota_obj @@ -202,21 +201,24 @@ def get_reservation(context, reservation_id): for delta in reserv_obj.resource_deltas)) -@utils.skip_exceptions(db_exc.DBError) @db_api.CONTEXT_WRITER def remove_reservation(context, reservation_id, set_dirty=False): - reservation = quota_obj.Reservation.get_object(context, id=reservation_id) - if not reservation: - # TODO(salv-orlando): Raise here and then handle the exception? - return - tenant_id = reservation.project_id - resources = [delta.resource for delta in reservation.resource_deltas] - reservation.delete() - if set_dirty: - # quota_usage for all resource involved in this reservation must - # be marked as dirty - set_resources_quota_usage_dirty(context, resources, tenant_id) - return 1 + try: + reservation = quota_obj.Reservation.get_object(context, + id=reservation_id) + if not reservation: + # TODO(salv-orlando): Raise here and then handle the exception? + return + tenant_id = reservation.project_id + resources = [delta.resource for delta in reservation.resource_deltas] + reservation.delete() + if set_dirty: + # quota_usage for all resource involved in this reservation must + # be marked as dirty + set_resources_quota_usage_dirty(context, resources, tenant_id) + return 1 + except db_exc.DBError: + context.session.rollback() @db_api.retry_if_session_inactive()