From b4eaa0520990f30519aaa073f352541f17b0577b Mon Sep 17 00:00:00 2001 From: armando-migliaccio Date: Thu, 7 Aug 2014 17:07:21 -0700 Subject: [PATCH] Fix session's InvalidRequestError because of nested rollback This patch addresses the issue by removing the extra nesting (which is effectively redundant). The longer story about this patch is the following: Race conditions may cause DBDuplicateEntry exceptions that require a transaction to be rollbacked back, and yet make the whole operation succeed. A classic example is what has been solved in commit fbc6b99. If the rollback is done in a nested transaction, the above mentioned exception is raised. To address the problem, we could use savepoints by means of sqlalchemy's begin_nested(); Even though this approach is preferable, it causes quite a bit of changes in the unit tests (because of sqlite); it may also require that certain DBMS, or certain DB backend configurations, support savepoints. In the end, the simpler approach was chosen. Closes-bug: #1354072 Change-Id: Ic9393319e55f71d681124bd3052e939724ebab6b --- neutron/scheduler/l3_agent_scheduler.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/neutron/scheduler/l3_agent_scheduler.py b/neutron/scheduler/l3_agent_scheduler.py index 265d2011a..8da4ed7d5 100644 --- a/neutron/scheduler/l3_agent_scheduler.py +++ b/neutron/scheduler/l3_agent_scheduler.py @@ -224,9 +224,8 @@ class ChanceScheduler(L3Scheduler): def schedule(self, plugin, context, router_id, candidates=None, hints=None): - with context.session.begin(subtransactions=True): - return self._schedule_router( - plugin, context, router_id, candidates=candidates, hints=hints) + return self._schedule_router( + plugin, context, router_id, candidates=candidates, hints=hints) def _choose_router_agent(self, plugin, context, candidates): return random.choice(candidates) @@ -237,9 +236,8 @@ class LeastRoutersScheduler(L3Scheduler): def schedule(self, plugin, context, router_id, candidates=None, hints=None): - with context.session.begin(subtransactions=True): - return self._schedule_router( - plugin, context, router_id, candidates=candidates, hints=hints) + return self._schedule_router( + plugin, context, router_id, candidates=candidates, hints=hints) def _choose_router_agent(self, plugin, context, candidates): candidate_ids = [candidate['id'] for candidate in candidates]