Slovník pojmů
Idempotence: bezpečné opakování operace
Timeout, retry nebo znovu spuštěný worker nemají vyrobit druhou objednávku, rezervaci ani platbu.
Stručná definice
Stejný požadavek může přijít vícekrát. Výsledek má zůstat jeden.
Idempotence je vlastnost operace, ne konkrétního HTTP slovesa ani databáze. Pokud služba zpracuje stejný příkaz znovu, má po dokončení zanechat stejný businessový stav jako po prvním úspěšném průchodu. Cílem je jedna lokální objednávka pro jednu marketplace objednávku, ne jedna objednávka za každý pokus o import.
Není nutné vrátit stejnou odpověď. První volání může vrátit 201 Created, druhé 200 s již existujícím výsledkem; obě jsou správně. Audit může evidovat dva přijaté požadavky. Podstatné je, aby se důležitý účinek neopakoval.
Použití
Kde duplicita bolí nejvíc
Ochrana je důležitá tam, kde klient nepozná, zda předchozí pokus dokončil práci.
- objednávky z marketplace nebo objednávkového formuláře
- potvrzení plateb, rezervace zboží a vratky
- import produktů, skladových pohybů a stavů objednávek
- fronty zpráv s opakovaným doručováním
- externí API s timeoutem, retry a dočasnou nedostupností
- plánované úlohy spuštěné na více instancích
Praktický příklad
Import marketplace objednávky po timeoutu
Marketplace pošle objednávku M-4821. Import ji uloží, ale odpověď se ztratí; marketplace proto odešle stejný požadavek znovu. Bez ochrany by vznikla druhá objednávka, rezervace skladu i e-mail.
Služba používá kombinaci marketplace a external_order_id jako stabilní identitu. Unikátní constraint znemožní dva současné zápisy, druhý pokus najde existující výsledek. Pokud externí ID není, klient odešle idempotency key svázaný s uživatelem, operací a otiskem vstupu.
Jak funguje
Od nejistého doručení k jednomu výsledku
Deduplikační identita musí obstát při souběhu i restartu procesu.
- Identita operace Klient použije externí ID objednávky nebo idempotency key pro jeden konkrétní příkaz.
- První zpracování Služba v transakci uloží cíl nebo záznam operace; constraint chrání před souběhem.
- Timeout či retry Klient zopakuje požadavek se stejnou identitou, protože nezná výsledek prvního pokusu.
- Deduplikace Služba najde dokončený či probíhající stav a vrátí výsledek nebo stav zpracování.
- Navazující účinky E-mail, platba nebo další API potřebují vlastní ochranu proti duplicitě.
Důležité vlastnosti
Identita, constraint, retry a stav
Jedna kontrola v PHP bez trvalé ochrany nestačí, když běží dva procesy současně.
Idempotency key
Jedinečný klíč od klienta pro opakování téhož příkazu. Server musí určit jeho platnost, rozsah a chování při použití stejného klíče s jiným vstupem.
Unikátní constraint
Pro souběžné vytvoření stejného záznamu je databázové omezení spolehlivější než vzor „nejdřív SELECT, potom INSERT“.
Deduplikace zpráv
Příjemce fronty ukládá ID zpracované zprávy nebo businessový klíč, protože po pádu workera může přijít znovu.
Retry a stav operace
Retry má omezené pokusy a rozestupy. Stavy processing, completed a failed určují, co udělá druhý požadavek.
Rozdílné ochrany
Idempotence není zámek ani exactly once
Tyto mechanismy řeší odlišnou část problému.
- Businessová identita
- Externí ID objednávky brání duplicitě přímo v modelu dat.
- Databázová transakce
- Spojí zápis objednávky a deduplikačního záznamu v rámci jedné databáze.
- Fronta a outbox
- Pomáhá předat navazující zprávu, příjemce ji ale stále musí zvládnout vícekrát.
- Distribuovaný zámek
- Omezuje souběh, není důkazem, že se práce dříve nestala.
Výhody a omezení
Bezpečnější retry, ne magická garance
Přínosy
- bezpečnější opakování nejistých síťových požadavků a zpráv
- méně duplicitních objednávek, rezervací a ručních oprav
- předvídatelné chování pro klienta při timeoutu
- jasně pojmenovaná identita businessové operace
Na co pozor
- key bez trvalého souběžně bezpečného uložení nepřežije restart ani paralelní požadavky
- příliš krátká retence klíče znovu otevře cestu k duplicitě
- stejný klíč s jiným vstupem nesmí systém potichu přijmout
- idempotence příjemce není end-to-end exactly once tvrzení
Hranice použití
Používat podle ceny chyby, ne jako povinný vzor.
Silná ochrana patří k platbám, objednávkám, skladovým rezervacím, importům a souběžným úlohám. Cena duplicitního účinku zde převyšuje cenu jednoznačné identity, constraintu a testů.
U nezávažného čtení dat nebo akce bez změny stavu může stačit běžná HTTP semantika. Idempotence nemá omlouvat složitý framework; má chránit konkrétní rizikový účinek.
Na co myslet
Ověřovat i nepříjemné scénáře
Návrh se vyplatí testovat simulací ztracené odpovědi, souběhu a opakovaného doručení.
- první zpracování, opakování i paralelní pokusy
- constraint odpovídající businessové identitě
- logování klíče, externího ID a výsledku bez citlivých dat
- retry a dohledatelný postup pro dlouhodobě neúspěšné zprávy
- vlastní strategie pro účinky mimo databázi
Časté otázky
Co idempotence znamená v praxi
Je POST vždy ne-idempotentní?
Na úrovni HTTP není POST obecně idempotentní. Konkrétní POST operaci lze navrhnout tak, aby se stejným idempotency key vytvořila právě jeden výsledek.
Musí druhý pokus vrátit stejnou HTTP odpověď?
Ne. Důležitý je stejný zamýšlený stav. Druhý pokus může vrátit dříve vytvořený zdroj nebo informaci, že operace stále běží.
Stačí Redis klíč s TTL?
Pro krátkou koordinaci může pomoci, ale není důkazem pro dlouhodobě důležitou objednávku či platbu. Po expiraci, výpadku nebo evikci může zmizet.
Je idempotence totéž co exactly once?
Ne. Idempotentní příjemce zvládne více doručení se stejným výsledkem. Exactly once je silnější end-to-end tvrzení.
Jak pracuji s integračními procesy v praxi
U důležitých synchronizací počítám s retry i nejistým výsledkem.
V integračních a e-commerce systémech navrhuji importy, synchronizace a chybové stavy tak, aby šly bezpečně dohledat a opakovat.