feat: base 优化safe_get_or_create以处理并发

This commit is contained in:
caoqianming 2024-12-30 10:24:12 +08:00
parent 2d42a485af
commit 564d8e1796
1 changed files with 14 additions and 8 deletions

View File

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