From 2712ccdeb7419844e8ad0fd99310d955e5815834 Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Sun, 19 Oct 2025 01:44:28 +0300 Subject: [PATCH] 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. --- core/vendors/__init__.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/core/vendors/__init__.py b/core/vendors/__init__.py index 31e8f957..052f50a7 100644 --- a/core/vendors/__init__.py +++ b/core/vendors/__init__.py @@ -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] - attribute.is_active = True - attribute.value_type = attr_value_type - attribute.save() + 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 + 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