Features: 1) Add retry mechanism with exponential backoff for saving attributes to handle deadlocks.

Fixes: 1) Remove unused `traceback` import; 2) Add missing import for `OperationalError`; 3) Prevent redundant saves for unchanged attributes.

Extra: 1) Simplify attribute save logic and improve efficiency; 2) Code cleanup for better readability.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-10-19 01:44:28 +03:00
parent 1fed75584e
commit 2712ccdeb7

View file

@ -1,6 +1,6 @@
import gzip
import json
import traceback
import time
from contextlib import suppress
from datetime import datetime
from decimal import Decimal
@ -14,6 +14,7 @@ from django.conf import settings
from django.core.files.base import ContentFile
from django.db import IntegrityError, transaction
from django.db.models import QuerySet
from django.db.utils import OperationalError
from core.elasticsearch import process_system_query
from core.models import (
@ -446,15 +447,27 @@ class AbstractVendor:
)
except Attribute.MultipleObjectsReturned:
attribute = Attribute.objects.filter(name=key, group=attr_group).order_by("uuid").first() # type: ignore [assignment]
fields_to_update: list[str] = []
if not attribute.is_active:
attribute.is_active = True
fields_to_update.append("is_active")
if attribute.value_type != attr_value_type:
attribute.value_type = attr_value_type
attribute.save()
fields_to_update.append("value_type")
if fields_to_update:
for attempt in range(5):
try:
attribute.save(update_fields=fields_to_update)
break
except OperationalError as e:
if "deadlock detected" in str(e):
time.sleep(0.1 * (2**attempt))
continue
raise
except IntegrityError:
async_logger.warning(f"IntegrityError while processing attribute {key!r}...")
return
attribute.save()
if not is_created:
return