feat: base 优化safe_get_or_create以处理并发

This commit is contained in:
caoqianming 2024-12-30 10:24:12 +08:00
parent c5d8f70251
commit 28c72e01b9
1 changed files with 14 additions and 8 deletions

View File

@ -112,15 +112,21 @@ class BaseModel(models.Model):
abstract = True
@classmethod
def safe_get_or_create(cls, **kwargs):
defaults = kwargs.pop('defaults', {})
for attempt in range(5):
def safe_get_or_create(cls, defaults=None, **kwargs):
defaults = defaults or {}
with transaction.atomic():
try:
return cls.objects.get_or_create(defaults=defaults, **kwargs)
except IntegrityError:
if attempt < 4:
time.sleep(0.1)
else:
ins = cls.objects.select_for_update().get(**kwargs)
return ins, False
except cls.DoesNotExist:
try:
ins = cls.objects.create(**defaults, **kwargs)
except IntegrityError:
try:
return cls.objects.get(**kwargs), False
except cls.DoesNotExist:
pass
raise
def handle_parent(self):