Use an independent transaction for _trait_sync

Provides a fix for the referenced bug by using an independent
transaction for the _trait_sync method, meaning it gets committed right
away regardless of what happens in the calling scope.

Change-Id: Ie9731d0df8cf52acdc7a442316a35798a4fed4cb
Closes-Bug: 1760322
This commit is contained in:
Eric Fried 2018-03-31 11:42:52 -05:00
parent 0d3d95926e
commit e2924ba237
2 changed files with 9 additions and 10 deletions

View File

@ -78,7 +78,9 @@ def _ensure_rc_cache(ctx):
@oslo_db_api.wrap_db_retry(max_retries=5, retry_on_deadlock=True)
@db_api.api_context_manager.writer
# Bug #1760322: If the caller raises an exception, we don't want the trait
# sync rolled back; so use an .independent transaction
@db_api.api_context_manager.writer.independent
def _trait_sync(ctx):
"""Sync the os_traits symbols to the database.

View File

@ -2258,19 +2258,16 @@ class ResourceProviderTraitTestCase(ResourceProviderBaseCase):
rp_obj.Trait.get_by_name, self.ctx, 'CUSTOM_TRAIT_A')
def test_bug_1760322(self):
# If the first hit to the traits table results in an exception, the
# sync transaction rolls back and the table stays empty. But
# _TRAITS_SYNCED got set to True, so it doesn't resync next time.
# Under bug # #1760322, if the first hit to the traits table resulted
# in an exception, the sync transaction rolled back and the table
# stayed empty; but _TRAITS_SYNCED got set to True, so it didn't resync
# next time.
try:
rp_obj.Trait.get_by_name(self.ctx, 'CUSTOM_GOLD')
except exception.TraitNotFound:
pass
# FIXME(efried): Bug #1760322: Should still succeed for a "real" trait.
# rp_obj.Trait.get_by_name(self.ctx, os_traits.HW_CPU_X86_AVX2)
# ...but instead raises TraitNotFound.
self.assertRaises(
exception.TraitNotFound,
rp_obj.Trait.get_by_name, self.ctx, os_traits.HW_CPU_X86_AVX2)
# Under bug #1760322, this raised TraitNotFound.
rp_obj.Trait.get_by_name(self.ctx, os_traits.HW_CPU_X86_AVX2)
def test_trait_destroy(self):
t = rp_obj.Trait(self.ctx)