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
This commit is contained in:
armando-migliaccio 2014-08-07 17:07:21 -07:00
parent 9bc3812687
commit cf69c5b4c3

View File

@ -224,9 +224,8 @@ class ChanceScheduler(L3Scheduler):
def schedule(self, plugin, context, router_id, def schedule(self, plugin, context, router_id,
candidates=None, hints=None): candidates=None, hints=None):
with context.session.begin(subtransactions=True): return self._schedule_router(
return self._schedule_router( plugin, context, router_id, candidates=candidates, hints=hints)
plugin, context, router_id, candidates=candidates, hints=hints)
def _choose_router_agent(self, plugin, context, candidates): def _choose_router_agent(self, plugin, context, candidates):
return random.choice(candidates) return random.choice(candidates)
@ -237,9 +236,8 @@ class LeastRoutersScheduler(L3Scheduler):
def schedule(self, plugin, context, router_id, def schedule(self, plugin, context, router_id,
candidates=None, hints=None): candidates=None, hints=None):
with context.session.begin(subtransactions=True): return self._schedule_router(
return self._schedule_router( plugin, context, router_id, candidates=candidates, hints=hints)
plugin, context, router_id, candidates=candidates, hints=hints)
def _choose_router_agent(self, plugin, context, candidates): def _choose_router_agent(self, plugin, context, candidates):
candidate_ids = [candidate['id'] for candidate in candidates] candidate_ids = [candidate['id'] for candidate in candidates]