【问题标题】:Shouldn't django's model get_or_create method be wrapped in a transaction?django 的模型 get_or_create 方法不应该包装在事务中吗?
【发布时间】:2011-02-16 15:59:51
【问题描述】:

我正在浏览 django 的源代码并查看了get_or_create。 不应该用事务包装吗?

谢谢

【问题讨论】:

  • 十年问题!我想知道为什么不让 get_or_create 成为原子的决定。有时我会看到由于非原子 get_or_create 导致的问题。

标签: django django-models


【解决方案1】:

查看this diff,它看起来像Revision 8315,已在get_or_create() 方法中显式处理。

更新

正如@reshefm 指出的那样,这在rev 8670 中得到了妥善解决,其中force_insert=True 被添加到obj.save() 以确保在竞争条件下,所有实例都将尝试插入(而不是回退到更新)所以只有一个人会成功,而其他人会失败。失败的实例将继续执行另一个get()。

在发布版本方面,此修复首先在 1.0 版本中引入。

【讨论】:

  • 再次查看您发布的同一版本的代码。 get 首先发生(没有事务),然后使用保存点保存记录,但这仍然意味着您会遇到竞争条件,因为 get 和 create 不是原子在一起的
  • 也许我遗漏了一些东西,但代码看起来不错。假设两个请求尝试获取并失败,则两者都将继续进行创建。假设.save() 是原子的,其中一个会成功,而另一个会失败。然后失败的继续执行获取以检索最近添加的数据。
  • 确实我看错了版本。这里的行:code.djangoproject.com/browser/django/trunk/django/db/models/… 解决了它。它强制插入。
  • @reshefm 关于force_insert 的好点子。将更新答案以供将来参考。
猜你喜欢
  • 1970-01-01
  • 2011-09-27
  • 1970-01-01
  • 2019-10-15
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
  • 2019-05-31
  • 1970-01-01
相关资源
最近更新 更多