django sql线程安全吗?
Posted
技术标签:
【中文标题】django sql线程安全吗?【英文标题】:django sql thread safe? 【发布时间】:2016-01-28 09:54:59 【问题描述】:假设我有这个代码:
product = Product.objects.get(name='something')
product.number_sold += 1
product.save()
如果在查询 number_sold 为 10 的过程中,然后在 save() 之前,这段代码同时运行,所以查询将再次返回 10,这意味着它会保存 number_sold = 11 两次? 换句话说,运行这个 django 视图的两个用户能否获得相同的 number_sold 字段值?
【问题讨论】:
【参考方案1】:为避免多线程/进程代码中的竞争条件,您应该使用F()-expressions
:
from django.db.models import F
product = Product.objects.get(name='something')
product.number_sold = F('number_sold') + 1
product.save()
【讨论】:
我阅读了 F 表达式,但我的问题仍然存在 - 两个用户是否仍然有可能使用给定的代码获得相同的 number_sold?如果我用@transaction.atomic 装饰我的视图,是否保证所有查询都将在相同的数据库状态下执行?问题代码只是一个例子。 是的,两个用户可能会在内存中获得相同的number_sold
,但在数据库级别number_sold
在每个save()
之后会有所不同。如果您将添加@transaction.atomic
,那么您将在某些线程中遇到异常。为防止此类异常,您可以使用 select_for_update()
方法 = docs.djangoproject.com/en/1.9/ref/models/querysets/…【参考方案2】:
您可以在单个查询中执行此操作:
Product.objects.filter(name='something').update(number_sold=F('number_sold')+1)
【讨论】:
以上是关于django sql线程安全吗?的主要内容,如果未能解决你的问题,请参考以下文章