Přeskočit na obsah

Read-after-write přes TTL cache — nová hodnota není vidět

import { Aside } from ‘@astrojs/starlight/components’;

Vícekrokový self-service flow „ulož hodnotu → ověř a aktivuj”: POST uloží rozpracovanou hodnotu do DB a vrátí ok: true, ale okamžitě navazující POST na ověřovací endpoint odpoví „Nejdřív zadejte hodnotu” a DELETE téže hodnoty „Žádný záznam”. Po ~30 sekundách začne vše fungovat samo — klasický příznak TTL cache.

Request-scoped kontext entity (zde tenant v multi-tenant aplikaci) se resolvuje přes sdílenou in-memory TTL cache (30 s), aby se nešahalo do DB při každém requestu:

// resolver s TTL cache 30 s
const cached = peekEntityByKey(key);
if (cached !== undefined) return cached;
const fresh = await db.entity.findUnique({ where: { key } });
cache.set(key, { entity: fresh, expiresAt: Date.now() + 30_000 });

Zapisující endpoint aktualizoval DB, ale cache neinvalidoval. Navazující endpointy četly entitu z kontextu (tedy z cache) a rozhodovaly podle staré hodnoty — read-after-write inkonzistence uvnitř jednoho flow.

Dvě opatření zároveň:

// 1) zapisující endpoint po commitu invaliduje cache
await db.entity.update({ where: { id }, data: { pendingValue } });
invalidateEntityCache(key);
// 2) rozhodovací kroky flow čtou čerstvě z DB, ne z cache kontextu
const fresh = await db.entity.findUnique({ where: { id: ctx.entity.id } });
if (!fresh?.pendingValue) return error("Nejdřív zadejte hodnotu.");

Cache kontext zůstává pro běžné čtení (zobrazování), ale nikdy není zdrojem pravdy pro krok, který bezprostředně navazuje na zápis.

Jak to příště odhalit dřív

Sekce “Jak to příště odhalit dřív”
  • Smoke test flow spouštět bez pauzy mezi kroky (ulož → hned ověř) — právě rychlá návaznost stale cache odhalí.
  • Při zavádění jakékoli TTL cache si vypsat všechna místa zápisu do cachované entity a ke každému doplnit invalidaci.
Přidal aiarchitekt.cz · 15. 7. 2026 2:00
Provozuje aiarchitekt.cz