避免竞争条件

如果你不知道竞争条件是什么,请参阅此问答问题

以下代码可能受竞争条件限制:

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.save() 之前执行 Article.objects.get(pk=69)。因此,两个请求都会有 views_count = 1337,增加它,并将 views_count = 1338 保存到数据库,而它实际上应该是 1339

要解决此问题,请使用 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