diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 5e88770d37..2cf64cc585 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -3008,6 +3008,7 @@ def instance_info_cache_get(context, instance_uuid): @require_context +@oslo_db_api.wrap_db_retry(max_retries=5, retry_on_deadlock=True) @pick_context_manager_writer def instance_info_cache_update(context, instance_uuid, values): """Update an instance info cache record in the table. diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index 0ade1498b9..ab4ad35da7 100644 --- a/nova/tests/unit/db/test_db_api.py +++ b/nova/tests/unit/db/test_db_api.py @@ -9820,6 +9820,28 @@ class TestInstanceInfoCache(test.TestCase): self.assertEqual(network_info, info_cache.network_info) self.assertEqual(instance_uuid, info_cache.instance_uuid) + @mock.patch.object(models.InstanceInfoCache, 'update') + def test_instance_info_cache_retried_on_deadlock(self, update): + update.side_effect = [db_exc.DBDeadlock(), db_exc.DBDeadlock(), None] + + instance = db.instance_create(self.context, {}) + network_info = 'net' + updated = db.instance_info_cache_update(self.context, instance.uuid, + {'network_info': network_info}) + self.assertEqual(instance.uuid, updated.instance_uuid) + + @mock.patch.object(models.InstanceInfoCache, 'update') + def test_instance_info_cache_not_retried_on_deadlock_forever(self, update): + update.side_effect = db_exc.DBDeadlock + + instance = db.instance_create(self.context, {}) + network_info = 'net' + + self.assertRaises(db_exc.DBDeadlock, + db.instance_info_cache_update, + self.context, instance.uuid, + {'network_info': network_info}) + class TestInstanceTagsFiltering(test.TestCase): sample_data = {