From 10d4a64c3a2e75dd360f960ada38709ae595bfe6 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 8 Sep 2025 09:28:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20base=20=E4=BC=98=E5=8C=96safe=5Fget=5Fo?= =?UTF-8?q?r=5Fcreate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/utils/models.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/apps/utils/models.py b/apps/utils/models.py index 6ccad9da..d561cad9 100755 --- a/apps/utils/models.py +++ b/apps/utils/models.py @@ -116,11 +116,27 @@ class BaseModel(models.Model): @classmethod def safe_get_or_create(cls, defaults=None, **kwargs): defaults = defaults or {} - lock_data = {**kwargs, **defaults} - lock_hash = hashlib.md5(str(lock_data).encode()).hexdigest() - lock_key = f"safe_get_or_create:{cls.__name__}:{lock_hash}" - with cache.lock(lock_key, timeout=10): - return cls.objects.get_or_create(**kwargs, defaults=defaults) + + for attempt in range(3): + try: + with transaction.atomic(): + # 先尝试获取(带锁) + try: + obj = cls.objects.select_for_update().get(**kwargs) + return obj, False + except cls.DoesNotExist: + # 不存在则创建 + obj = cls(**kwargs, **defaults) + obj.save() + return obj, True + except IntegrityError: + # 发生唯一约束冲突时重试 + if attempt == 2: + raise + time.sleep(0.1 * (attempt + 1)) + except Exception: + # 其他异常直接抛出 + raise def handle_parent(self):