Выбор ответа Middle Django ORM и N+1 спрашивают часто обновлено

Атомарное увеличение счётчика

Вопрос

Как увеличить счётчик просмотров статьи без гонки между параллельными запросами?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Article.objects.filter(pk=pk).update(views=F('views') + 1). F("views") + 1 превращается в SQL SET views = views + 1, и база увеличивает значение атомарно.

Варианты ответа

  1. a = Article.objects.get(pk=pk); a.views += 1; a.save()
  2. Article.objects.filter(pk=pk).update(views=F('views') + 1)правильный ответ
  3. a.views = a.views + 1 внутри try/except
  4. Хранить счётчик в глобальной переменной процесса

Разбор

F("views") + 1 превращается в SQL SET views = views + 1, и база увеличивает значение атомарно. Вариант «прочитал, увеличил, сохранил» теряет обновления: два запроса прочитают 10 и оба запишут 11. try/except от гонки не спасает, а глобальная переменная живёт в одном процессе и теряется при перезапуске.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.