避免競爭條件

如果你不知道競爭條件是什麼,請參閱此問答問題

以下程式碼可能受競爭條件限制:

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