Выбор ответа 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. Запись в БД и запись в кеш это две отдельные операции.
Варианты ответа
- Ключ будет удалён дважды, и следующий запрос упадёт
- В кеше останется значение, расходящееся с БД, до TTLправильный ответ
- Redis выбросит ошибку конкурентной записи в один ключ
- Никакой: запись в БД и в кеш выполняются атомарно
Разбор
Запись в БД и запись в кеш это две отдельные операции. Запрос A обновил БД, затем B обновил БД и кеш, затем A записал в кеш своё устаревшее значение. Теперь кеш расходится с БД до истечения TTL. Поэтому при изменении ключ обычно удаляют (следующее чтение возьмёт свежие данные), и всегда ставят TTL как страховку. Redis не выдаёт ошибок конкуренции для SET, а атомарности между БД и кешем нет.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.