Короткий ответ
Между записью в БД и обновлением/удалением кеша может вклиниться параллельное чтение, которое закеширует устаревшее значение; надёжнее удалять кеш после коммита БД-транзакции и использовать короткий TTL как страховочную сетку.
Как это работает подробнее
Если порядок — «удалить кеш, затем обновить БД», параллельный читатель между шагами может прочитать из БД старое значение и закешировать его уже после удаления, оставив устаревшие данные до TTL.
Пример кода
example.py
def update_price(product_id, new_price):
db.update_price(product_id, new_price) # 1) обновить БД
cache.delete(f"product:{product_id}") # 2) затем инвалидировать кеш
# окно гонки: read, начавшийся до (1) и завершившийся после (2), может закешировать старое значениеЧто использовать на практике
- Практика. Полностью убрать гонку без блокировок или версионирования сложно; снижают риск коротким TTL, версионированием записи (кешировать с номером версии) либо последовательной обработкой через очередь событий.
Подводные камни
- Риск. Считать, что порядок «сначала БД, потом кеш» полностью устраняет гонку — он лишь снижает окно её возникновения; не задавать TTL вообще при invalidate-on-write.