【发布时间】:2015-04-29 05:05:30
【问题描述】:
任何人都可以就以下问题提出建议:
我有一个自定义的 get_or_create 方法,它检查多个字段并在创建时执行一些花哨的操作:
def fancy_get_or_create(name):
object = self.fancy_get(name)
if not object:
object = self.fancy_create(name)
return object
def fancy_get(name):
return self.filter(Q(name=name) | Q(alias=name)).first()
def fancy_create(name):
name = self.some_preprocessing(name)
return self.create(name=name, alias=name)
有一个竞争条件,一个请求将检查对象是否存在,什么也找不到,然后开始创建它。在该请求完成创建对象之前,另一个请求进来寻找相同的对象,什么也没找到,然后开始创建新对象。这个请求会失败,因为数据库有一些唯一性约束(前一个请求刚刚创建了对象,所以第二个请求会失败)。
有什么方法可以阻止请求 2 在请求 1 完成之前查询数据库?我正在阅读有关事务管理的内容,但它似乎不是解决方案,因为问题不是部分更新(这表明原子事务),而是需要让第二个请求等到第一个请求完成。
谢谢!
更新: 这就是我的选择:
try:
return self.fancy_get(name) or self.fancy_create(name)
except IntegrityError:
return self.fancy_get(name)
【问题讨论】:
-
我不认为这是重复的,但这可能会给你一些选择:stackoverflow.com/questions/1030270/…
-
我知道这个问题已经得到解答,但是您应该在执行读取之前采取数据库隔离级别来锁定数据库,基本上是在您的 get_or_create 调用上创建一个互斥锁。 en.wikipedia.org/wiki/Isolation_(database_systems)
标签: mysql django race-condition