Django 避免比赛条件

示例

如果您不知道比赛条件是什么,请参阅此问答问题。

以下代码可能会受竞争条件的影响:

article = Article.objects.get(pk=69)
article.views_count += 1
article.save()

如果views_count等于1337,将导致这样的查询:

UPDATE app_article SET views_count = 1338 WHERE id=69

如果两个客户端同时访问此文章,则可能会发生第二个HTTP请求Article.objects.get(pk=69)在第一个执行之前执行。因此,两个请求都将具有,增加它并保存到数据库,而实际上应该是。article.save()views_count = 1337views_count = 13381339

要解决此问题,请使用F()表达式:

article = Article.objects.get(pk=69)
article.views_count = F('views_count') + 1
article.save()

另一方面,这将导致这样的查询:

UPDATE app_article SET views_count = views_count + 1 WHERE id=69