get_or_create()线程是否安全 [英] Is get_or_create() thread safe
问题描述
我有一个只能使用 get_or_create(session = session)
访问的Django模型,其中session是另一个Django模型的外键。
I have a Django model that can only be accessed using get_or_create(session=session)
, where session is a foreign key to another Django model.
由于我只能通过 get_or_create()
进行访问,我可以想像,我只会有一个实例与会话的关键。但是,我已经发现了多个具有密钥的实例到同一个会话。发生什么事?这是一个竞争条件,还是 get_or_create()
原子运算?
Since I am only accessing through get_or_create()
, I would imagine that I would only ever have one instance with a key to the session. However, I have found multiple instances with keys to the same session. What is happening? Is this a race condition, or does get_or_create()
operate atomically?
推荐答案
p> Actualy它不是线程安全的,您可以查看QuerySet对象的get_or_create方法的代码,其基本原理如下:
Actualy it's not thread-safe, you can look at the code of the get_or_create method of the QuerySet object, basicaly what it does is the following :
try:
return self.get(**lookup), False
except self.model.DoesNotExist:
params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
params.update(defaults)
obj = self.model(**params)
sid = transaction.savepoint(using=self.db)
obj.save(force_insert=True, using=self.db)
transaction.savepoint_commit(sid, using=self.db)
return obj, True
所以两个线程可能会弄清楚实例在数据库中不存在,并开始创建一个新的,然后连续保存。
So two threads might figure-out that the instance does not exists in the DB and start creating a new one, before saving them consecutively.
这篇关于get_or_create()线程是否安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!