feat: base 添加locked_get_or_create
This commit is contained in:
parent
43abcbaa48
commit
3417515e72
|
|
@ -151,6 +151,31 @@ class BaseModel(models.Model):
|
||||||
time.sleep(0.1 * (attempt + 1))
|
time.sleep(0.1 * (attempt + 1))
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def locked_get_or_create(cls, defaults: dict, **kwargs):
|
||||||
|
"""
|
||||||
|
仅用于事务内
|
||||||
|
并发安全的 get_or_create
|
||||||
|
"""
|
||||||
|
if not connection.in_atomic_block:
|
||||||
|
raise RuntimeError("locked_get_or_create 必须在事务中调用")
|
||||||
|
|
||||||
|
defaults = defaults or {}
|
||||||
|
|
||||||
|
qs = cls.objects.select_for_update().filter(**kwargs)
|
||||||
|
|
||||||
|
cnt = qs.count()
|
||||||
|
if cnt > 1:
|
||||||
|
raise RuntimeError(
|
||||||
|
f"{cls.__name__} 数据异常:定位条件 {kwargs} 命中 {cnt} 条"
|
||||||
|
)
|
||||||
|
|
||||||
|
if cnt == 1:
|
||||||
|
return qs.get(), False
|
||||||
|
|
||||||
|
obj = cls.objects.create(**kwargs, **defaults)
|
||||||
|
return obj, True
|
||||||
|
|
||||||
def handle_parent(self):
|
def handle_parent(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue