Merge branch 'master' of http://gitea.xxhhcty.xyz:8080/zcdsj/factory
This commit is contained in:
commit
0e783a92e0
|
@ -116,11 +116,27 @@ class BaseModel(models.Model):
|
||||||
@classmethod
|
@classmethod
|
||||||
def safe_get_or_create(cls, defaults=None, **kwargs):
|
def safe_get_or_create(cls, defaults=None, **kwargs):
|
||||||
defaults = defaults or {}
|
defaults = defaults or {}
|
||||||
lock_data = {**kwargs, **defaults}
|
|
||||||
lock_hash = hashlib.md5(str(lock_data).encode()).hexdigest()
|
for attempt in range(3):
|
||||||
lock_key = f"safe_get_or_create:{cls.__name__}:{lock_hash}"
|
try:
|
||||||
with cache.lock(lock_key, timeout=10):
|
with transaction.atomic():
|
||||||
return cls.objects.get_or_create(**kwargs, defaults=defaults)
|
# 先尝试获取(带锁)
|
||||||
|
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):
|
def handle_parent(self):
|
||||||
|
|
Loading…
Reference in New Issue