Выбор ответа Middle Кеширование обновлено

Удалить или обновить ключ

Вопрос

При обновлении товара код делает так. Какая проблема возможна при двух параллельных обновлениях одного товара?

async function updateProduct(id, data) {
  const product = await db.products.update(id, data);
  await redis.set(`product:${id}`, JSON.stringify(product), 'EX', 3600);
}

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

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

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

Коротко

Правильный ответ: В кеше останется значение, расходящееся с БД, до TTL. Запись в БД и запись в кеш это две отдельные операции.

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

  1. Ключ будет удалён дважды, и следующий запрос упадёт
  2. В кеше останется значение, расходящееся с БД, до TTLправильный ответ
  3. Redis выбросит ошибку конкурентной записи в один ключ
  4. Никакой: запись в БД и в кеш выполняются атомарно

Разбор

Запись в БД и запись в кеш это две отдельные операции. Запрос A обновил БД, затем B обновил БД и кеш, затем A записал в кеш своё устаревшее значение. Теперь кеш расходится с БД до истечения TTL. Поэтому при изменении ключ обычно удаляют (следующее чтение возьмёт свежие данные), и всегда ставят TTL как страховку. Redis не выдаёт ошибок конкуренции для SET, а атомарности между БД и кешем нет.

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

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