Fixing a bug in DB API method that acquires entity lock
* Before this change method acquire_lock() would override all changes made for an entity by a concurrent transaction when calling entity.update() although one line before it should have read this entity from DB and update only a timestamp to acquire the lock. The solution is just to append "FOR UPDATE" to an SQL statement when fetching an entity from DB. In this case we don't need to artificially update a timestamp at all. * Unit test for MySQL or Postgres is currently impossible, all unit tests are run against sqlite * Adding "PYTHONHASHSEED = 0" into "venv" environment in tox.ini to prevent sphinx from failing. It should be added to "venv" because docs building run with command "tox -evenv -- python setup.py build_sphinx". * Fixed minor style issues Change-Id: Ia749f397e18e927820ff7ae6bac7d28dc2aa2ba4
This commit is contained in:
parent
fdb24bd697
commit
3e9aa8b310
@ -21,7 +21,6 @@ from oslo_db import exception as db_exc
|
||||
from oslo_db import sqlalchemy as oslo_sqlalchemy
|
||||
from oslo_db.sqlalchemy import utils as db_utils
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import timeutils
|
||||
from oslo_utils import uuidutils
|
||||
import sqlalchemy as sa
|
||||
|
||||
@ -96,20 +95,16 @@ def acquire_lock(model, id, session=None):
|
||||
# will be up-to-date from the DB and not from cache.
|
||||
session.expire_all()
|
||||
|
||||
if b.get_driver_name() != 'sqlite':
|
||||
entity = _get_one_entity(model, id)
|
||||
entity.update({'updated_at': timeutils.utcnow()})
|
||||
|
||||
else:
|
||||
if b.get_driver_name() == 'sqlite':
|
||||
# In case of 'sqlite' we need to apply a manual lock.
|
||||
sqlite_lock.acquire_lock(id, session)
|
||||
entity = _get_one_entity(model, id)
|
||||
|
||||
return entity
|
||||
return _lock_entity(model, id)
|
||||
|
||||
|
||||
def _get_one_entity(model, id):
|
||||
# Get entity by ID and expect exactly one object.
|
||||
return _secure_query(model).filter(model.id == id).one()
|
||||
def _lock_entity(model, id):
|
||||
# Get entity by ID in "FOR UPDATE" mode and expect exactly one object.
|
||||
return _secure_query(model).with_for_update().filter(model.id == id).one()
|
||||
|
||||
|
||||
def _secure_query(model, *columns):
|
||||
|
@ -70,8 +70,8 @@ class WorkflowController(object):
|
||||
according to this workflow type rules and identifies a list of
|
||||
commands needed to continue the workflow.
|
||||
|
||||
:param: task_ex: Task execution to rerun.
|
||||
:param: reset: If true, then purge action executions for the tasks.
|
||||
:param task_ex: Task execution to rerun.
|
||||
:param reset: If true, then purge action executions for the tasks.
|
||||
:param env: A set of environment variables to overwrite.
|
||||
:return: List of workflow commands (instances of
|
||||
mistral.workflow.commands.WorkflowCommand).
|
||||
@ -88,6 +88,7 @@ class WorkflowController(object):
|
||||
def is_error_handled_for(self, task_ex):
|
||||
"""Determines if error is handled for specific task.
|
||||
|
||||
:param task_ex: Task execution perform a check for.
|
||||
:return: True if either there is no error at all or
|
||||
error is considered handled.
|
||||
"""
|
||||
|
2
tox.ini
2
tox.ini
@ -39,7 +39,9 @@ commands =
|
||||
oslo-config-generator --config-file tools/config/config-generator.mistral.conf \
|
||||
--output-file etc/mistral.conf.sample
|
||||
|
||||
#set PYTHONHASHSEED=0 to prevent wsmeext.sphinxext from randomly failing.
|
||||
[testenv:venv]
|
||||
setenv = PYTHONHASHSEED=0
|
||||
commands = {posargs}
|
||||
|
||||
#set PYTHONHASHSEED=0 to prevent wsmeext.sphinxext from randomly failing.
|
||||
|
Loading…
Reference in New Issue
Block a user