DOCUMENT / LOCALSYS / 04TRACEABLE SOURCESREADER MODE

Sistemi, infrastruktura in odpornost

EN KLIK, DVE NAROČILI

Zakaj lahko aplikacija po izgubljenem odgovoru podvoji naročilo in kaj mora ohraniti ob ponovnem poskusu.

≈ 8min branja9viri13. 10. 2026preverjeno

Poslovna aplikacija pošlje naročilo v drugo storitev. Ta ga sprejme, shrani in mu dodeli številko. Preden potrditev doseže odjemalca, se povezava prekine. Aplikacija po izteku čakanja ponovi zahtevo, ker ima vgrajen mehanizem za odpravljanje začasnih komunikacijskih napak. Storitev ponovno poslano zahtevo obravnava kot novo naročilo in ustvari še en zapis. Uporabnik je gumb pritisnil samo enkrat.

Uporabnik ob prenosniku, na katerem sta prikazani dve naročili, med njima pa simbol ponovnega poskusa.
Izvorna naslovna grafika članka iz prvotne objave. · Vir: Vestigo / prvotna objava

V tem hipotetičnem primeru odjemalec ne ve, da je bilo naročilo že ustvarjeno. Podvojitev nastane, ker sistem ponovljene zahteve ne poveže s prvotnim naročilom. Mehanizem za odpravljanje komunikacijskih težav tako ustvari dodatno poslovno obveznost. Samodejni ponovni poskusi so običajen del integracij. Microsoftov arhitekturni vzorec Retry jih predvideva pri prehodnih napakah, hkrati pa opozarja na uspešno obdelano zahtevo, katere odgovor se ni vrnil. Če operacija ni zasnovana za varno ponavljanje, lahko naslednji poskus ponovno povzroči isti poslovni učinek. [1]

Kaj ostane za prekinjeno povezavo

Ko odjemalec preneha čakati, je izid lahko še odprt. Zahteva morda ni dosegla storitve, lahko je v obdelavi, lahko pa je dejanje že opravljeno in manjka le odgovor. Sam iztek časa ne loči teh možnosti. Daljše čakanje utegne zmanjšati število ponovitev, ne določi pa, kako bo storitev naslednjo zahtevo povezala s prejšnjo.

Tudi odgovor z napako ne zagotavlja, da pred njim ni nastala sprememba. Stripe za API v1 opozarja na nedoločen izid ob HTTP 500. Pred novim poskusom z novo oznako operacije svetuje razrešitev prvotnega izida s pregledom objekta ali dogodkov storitve. [2]

Za poslovno aplikacijo je takšno vmesno stanje zahtevnejše od jasne zavrnitve. Če ga prikaže kot »naročilo ni uspelo«, lahko uporabnika spodbudi k novi oddaji, čeprav prejšnje naročilo še obstaja ali nastaja. Sporočilo »izid naročila še preverjamo« bi bolje opisalo dejansko stanje, vendar potrebuje tudi nadaljevanje postopka. Aplikacija mora ohraniti povezavo s prvotno operacijo, da lahko pozneje pridobi njen rezultat ali jo preda v obravnavo podporni ekipi.

Ponoviti zahtevo, ohraniti učinek

Idempotentnost je lastnost operacije, pri kateri več enakih zahtev povzroči enak predvideni učinek kot ena sama. RFC 9110 tako semantiko določa za PUT, DELETE in varne metode, med njimi GET; konkretni vmesnik jo mora tudi spoštovati. Lastnost se nanaša na zahtevani učinek. Strežnik lahko vsak poskus posebej zabeleži, odgovori na ponovitve pa se lahko razlikujejo. [3] Pri izbrisu določenega objekta ga po prvi uspešni izvedbi ni več. Ponovitev iste zahteve ne izbriše še drugega objekta, strežnik pa lahko odgovori drugače, ker prvega ne najde. Pri operaciji »ustvari novo naročilo« bi vsaka ponovitev brez dodatnega dogovora lahko ustvarila nov objekt.

RFC odjemalcu odsvetuje samodejno ponavljanje neidempotentne zahteve, razen kadar pozna idempotentno semantiko konkretne operacije ali lahko ugotovi, da prvotna zahteva ni bila izvedena. POST lahko takšno zaščito dobi v zasnovi API-ja. Sama izbira metode je ne ustvari. [3]

V zasnovi, ki prepozna ponovitev, obe oddaji ostaneta povezani z isto poslovno operacijo. Storitev za že ustvarjeno naročilo lahko vrne njegov rezultat. Če obdelava še poteka, drugo zahtevo poveže z njo.

Oznaka pripada naročilu

Pogosta rešitev za prepoznavanje ponovitev je ključ za zagotavljanje idempotentnosti, ki ga odjemalec pošlje skupaj z zahtevo. Označuje posamezno operacijo v dogovorjenem obsegu in ostane isti pri njenih ponovnih poskusih. Prvotna oddaja naročila in oddaja po prekinitvi bi nosili isto oznako, novo naročilo pa bi dobilo drugo. Primerjava vsebine ni vedno dovolj. AWS v Builders’ Library opozori, da lahko uporabnik namenoma zahteva dva enaka navidezna strežnika. Enaki parametri takrat pomenijo dve želeni operaciji. Njihov pristop uporablja identifikator zahteve, ki ga poda odjemalec, da lahko storitev razlikuje ponovitev od nove operacije. [4]

Dogovor odpove, če odjemalec pred vsakim poskusom ustvari novo oznako. Enako se lahko zgodi po ponovnem zagonu, če prejšnji ključ ostane samo v pomnilniku. Stripe za API v1 priporoča trajno hrambo ključa pri ponovitvah prek ločenih klicev odjemalske knjižnice ali po ponovnem zagonu procesa. Odjemalec isti ključ uporabi pri vsakem poskusu. [2] Ključ mora ohraniti tudi povezavo s pomenom zahteve. Če je prvotna operacija že evidentirana pod njim, sprememba količine ali drugega pomembnega parametra ne predstavlja več njene preproste ponovitve. Stripe pri API v1 primerja parametre s prvotnimi in ob neskladju vrne napako. Rezultat se shrani po začetku izvajanja; pri zavrnitvi zaradi neveljavnih parametrov pred tem začetkom se ne shrani. [5] Pred popravljeno oddajo mora biti ugotovljeno, da prvotna operacija ni uspela in ni več v obdelavi. Z novim ključem nedoločenega izida ne smemo obiti. [2]

Med preverjanjem in zapisom

Dva delovna procesa lahko skoraj hkrati prejmeta isti ključ. Oba v evidenci ne najdeta zapisa zanj in vsak začne ustvarjati naročilo. Poznejši zapis ključa podvojitve ne prepreči, saj sta obe izvedbi že stekli. AWS pri opisanem pristopu povezuje evidentiranje ključa in spreminjanje stanja v atomarno operacijo. S tem preprečuje položaj, v katerem je vir ustvarjen, njegov ključ pa ni zabeležen, ali je ključ zabeležen brez nastanka vira. [4] Pri naročilu v eni podatkovni zbirki je lahko del rešitve transakcija z ustrezno omejitvijo enoličnosti. Skupaj mora zajeti zapis ključa in nastanek naročila. Nadaljnje dejanje v zunanji storitvi potrebuje svojo obravnavo ponovitve, saj ga lokalna transakcija sama ne zajame.

Ko naročilo nadaljuje pot prek posrednika sporočil, se spremeni tudi mesto prepoznavanja dvojnikov. Azure Service Bus pri vključeni funkciji zaznavanja dvojnikov in izključenem particioniranju preverja MessageId znotraj nastavljenega obdobja. Ponovno poslano sporočilo z že evidentirano oznako sprejme, nato pa zavrže; drugih delov njegove vsebine pri tem ne primerja. Pri particioniranju se za enoličnost upošteva še PartitionKey. [6] Tako posrednik izloči podvojena sporočila v navedenem obsegu; poslovno obdelavo opravlja prejemnik. Prejemnik lahko sporočilo prevzame, trajno spremeni podatek v svoji zbirki in se ustavi pred uspešno potrditvijo obdelave posredniku. Če sporočilo znova prispe, mora prepoznati že opravljeni učinek. Google za funkcijo exactly-once delivery v Pub/Sub priporoča ohranitev podatkov o napredku obdelave do uspešne potrditve. Če potrditev odpove, prejemnik te podatke uporabi za preprečevanje ponovnega dela. Zagotovilo velja za naročnine s prevzemanjem sporočil (pull) in za prejemnike, ki se povezujejo s storitvijo v isti regiji. [7]

Google opozarja še na podvojitve pri objavljanju: če pošiljatelj ob ponovitvi opravi novo objavo, lahko nastanejo različni identifikatorji sporočil. Enako poslovno naročilo je tedaj predstavljeno z več sporočili tudi ob vključeni funkciji exactly-once delivery. [7] Prejemnik, ki preverja samo transportno oznako, jih zato lahko obravnava ločeno. Povezava z izvorno poslovno operacijo mu omogoči ugotoviti, da gre za ponovno posredovanje istega naročila.

Kje in koliko časa velja ključ

Evidenca že obravnavanih operacij ima življenjsko dobo. Pri Stripe API v1 se ključi lahko odstranijo, ko so stari najmanj 24 ur. Če odjemalec isti ključ uporabi po odstranitvi, lahko nastane nova zahteva. [5] Večdnevna čakalna vrsta ne sme predpostaviti, da stara oznaka še vedno varuje prvotno operacijo. Stripe za nerešen izid po prvih 24 urah svetuje ustavitev ponovitev in preverjanje prvotne operacije. Ponovna uporaba starega ključa ali ustvaritev novega tega izida ne razreši. [2]

Med različicami istega ponudnika se razlikuje tudi vrnjeni rezultat. Stripe API v1 po začetku izvajanja shrani status in telo prvega odgovora za ključ, tudi napako 500. [5] API v2 uspešne operacije ob ponovitvi ne izvede znova in vrne posodobljen odgovor. Neuspešni del operacije poskuša dokončati, kadar je to mogoče; sicer vrne napako z razlago. Za prepoznavo ponovitve določa isti ključ, isti API, isti račun oziroma peskovnik in 30-dnevno obdobje. [8] Ponavljanje zahteve, ki vrača že shranjeno napako, samo po sebi še ne razrešuje odprtega poslovnega izida.

Amazon EC2 za RunInstances razlikuje regionalno in consko idempotentnost. Consko pravilo velja, kadar zahteva cono razpoložljivosti določi izrecno ali jo posredno določi s parametrom SubnetId, torej z izbiro podomrežja. Če je ne določi na nobenega od teh načinov, velja regionalno pravilo. Pri regionalni idempotentnosti lahko ista zahteva z istim ClientToken ustvari primerek v drugi regiji; pri conski lahko isti ključ uporabimo za zagon v drugi coni iste regije. [9] Preusmeritev v nadomestno okolje je lahko nova izvedba po pravilih storitve, čeprav jo odjemalec razume kot nadaljevanje prvotnega poskusa. Odjemalec mora preveriti tudi, ali v prvotnem okolju že obstaja primerek, povezan z isto poslovno operacijo.

Preizkus z izgubljenim odgovorom

Integracija, ki pri običajnem testu uspešno odda naročilo in dobi potrditev, še ni pokazala, kako obravnava negotov izid. Pri uporabnem preizkusu storitev najprej trajno zapiše naročilo, nato se prepreči, da bi odgovor dosegel odjemalca. Ta ponovi zahtevo z istim ključem in parametri. Pregled poveže oba poskusa z identifikatorjem nastalega naročila ter preveri število naročil in pripadajoče spremembe zaloge ali drugih podatkov v obravnavanem postopku. Iz zapisa mora biti razvidno, da je bilo prvotno naročilo trajno shranjeno pred ponovitvijo. Brez tega bi lahko opazovali zgolj prvo uspešno oddajo po neuspelem začetnem poskusu.

Drug preizkus po oddaji in izgubi odgovora ustavi odjemalca. Po ponovnem zagonu mora ta najti operacijo z nerazrešenim izidom in uporabiti njen ohranjeni ključ. Vzporedni poskusi pokažejo, ali mehanizem deluje tudi med prvo obdelavo. Preveriti je smiselno še zahtevo z drugačnimi parametri pod že uporabljenim ključem ter ravnanje po izteku obdobja zaščite. Pri prvi je pomembna primerjava z dokumentiranimi pravili vmesnika, pri drugi pa preverjanje prvotnega izida pred morebitno novo izvedbo. Če postopek vključuje posrednik sporočil, naj preizkus zajame tudi trajni zapis pri prejemniku pred uspešno potrditvijo posredniku. Ob ponovni dostavi se preveri, ali je isti poslovni učinek nastal še enkrat.

Podporna ekipa za razrešitev naročila potrebuje povezavo med oznako operacije, posameznimi poskusi, nastalim naročilom in njegovim stanjem. Zapis »zahteva ni uspela« je za to premalo. Če avtomatika izida ne more ugotoviti, mora ohraniti podatke, s katerimi se lahko obravnava nadaljuje brez slepe ponovne oddaje.

Pri uvodnem primeru je odločilno, ali obe oddaji vodita do istega naročila in pripadajoče obdelave zaloge. Če ponovitev ustvari dodatno naročilo, je sistem en uporabnikov klik obravnaval kot dve poslovni operaciji.

EVIDENCE PROFILE

Dokazni profil članka

Profil pokaže vrsto dokazne podlage in omejitve osrednjega argumenta.

OSREDNJI DOKAZPri ponovnih poskusih mora sistem ohraniti identiteto poslovne operacije in znati razrešiti nedoločen izid; transportni retry brez idempotentnosti lahko podvoji učinek.
RAZISKAVE0
DOKUMENTACIJA9
PREDOBJAVE0
UREDNIŠKI PREIZKUSNE
PREVERJENO2026-10-13

Viri

  1. 01PRIMARY DOCUMENTATIONMicrosoft
    Microsoft Learn: Retry pattern. Azure Architecture Center; Idempotency in General guidance.Odpri vir ↗
  2. 02PRIMARY DOCUMENTATIONStripe
    Stripe: Advanced error handling. Server errors, POST requests in Sending idempotency keys; navodila o ponavljanju za API v1.Odpri vir ↗
  3. 03STANDARDInternet Engineering Task Force (IETF)
    Fielding, R. T., Nottingham, M. in Reschke, J.: RFC 9110: HTTP Semantics. Junij 2022. Razdelek 9.2.2, Idempotent Methods.Odpri vir ↗
  4. 04PRIMARY DOCUMENTATIONAmazon Web Services (AWS)
    Featonby, M.: Making retries safe with idempotent APIs. AWS Builders’ Library; Reducing client complexity in razlaga atomarnega zapisa.Odpri vir ↗
  5. 05PRIMARY DOCUMENTATIONStripe
    Stripe: Idempotent requests. Pravila API v1 za parametre, shranjevanje rezultata in hrambo ključev.Odpri vir ↗
  6. 06PRIMARY DOCUMENTATIONMicrosoft
    Microsoft Learn: Duplicate detection in Azure Service Bus. How it works.Odpri vir ↗
  7. 07PRIMARY DOCUMENTATIONGoogle
    Google Cloud: Exactly-once delivery. Pub/Sub; uvodne smernice, Regional considerations in Things to know.Odpri vir ↗
  8. 08PRIMARY DOCUMENTATIONStripe
    Stripe: API v2 overview. Idempotency in Idempotency differences between API v1 and API v2.Odpri vir ↗
  9. 09PRIMARY DOCUMENTATIONAmazon Web Services (AWS)
    Amazon Web Services: Ensuring idempotency in Amazon EC2 API requests. RunInstances idempotency. Dokumentacija preverjena 13. oktobra 2026. Uvodni primer je hipotetičen. Opisani preizkusi so predlogi, izpeljani iz navedenih mehanizmov; njihova izvedba in rezultati niso predmet članka.Odpri vir ↗