Comenzi duplicate la lucrul cu API: cauze și protecție
De ce apar duplicate după o singură acțiune
Proprietarul panoului poate apăsa butonul o singură dată și poate vedea mai multe comenzi identice: pentru abonați, vizualizări, reacții sau alt serviciu. De obicei problema nu este în clic în sine, ci în lanțul dintre client, API, baza de date și furnizor.
Din perspectiva serverului, „o singură solicitare” nu înseamnă întotdeauna una singură. Clientul poate să nu fi primit răspuns, să fi retrimis solicitarea, iar prima operațiune era deja salvată. Uneori comanda este creată o singură dată în baza de date a panoului, dar este trimisă de două ori către furnizor. Acestea sunt scenarii diferite și se corectează în mod diferit.
Timeout-ul nu înseamnă că comanda nu a fost creată
Cea mai frecventă cauză este că clientul așteaptă răspunsul un timp limitat. Serverul primește solicitarea, creează comanda, dar răspunde după timeout-ul stabilit. Clientul consideră operațiunea eșuată și o retrimite.
Ca rezultat, prima comandă există deja în baza de date, iar a doua solicitare creează încă una. Acest lucru se întâmplă mai ales la un răspuns lent al API-ului extern, la o coadă supraîncărcată sau la o conexiune instabilă între servicii.
Timeout-ul indică doar absența răspunsului, nu absența procesării solicitării.
Repetări automate pe partea clientului
Bibliotecile pentru solicitări HTTP, sarcinile din fundal și serviciile de integrare repetă destul de des solicitarea automat. Motivul poate fi o eroare de conexiune, un cod de răspuns al serverului, o întrerupere a rețelei sau un răspuns prea lent.
Repetarea în sine este utilă: reduce numărul de comenzi pierdute la defecțiuni temporare. Dezavantajul acestei abordări este că, fără protecție împotriva procesării repetate, transformă orice instabilitate a rețelei în duplicate.
- repetarea poate fi lansată în codul site-ului sau al botului;
- sarcina poate fi repornită de coadă;
- solicitarea poate fi repetată de un proxy sau de un modul de integrare;
- operatorul poate retrimite manual comanda după o eroare.
Solicitarea repetată ajunge înaintea primului răspuns
Uneori două solicitări identice ajung într-adevăr la API aproape simultan. De exemplu, utilizatorul a trimis formularul de două ori, frontend-ul nu a blocat butonul sau sarcina din fundal a pornit din nou înainte de finalizarea primei.
Dacă handler-ul verifică mai întâi existența comenzii și apoi o creează, două operațiuni paralele pot trece verificarea simultan. Fiecare va vedea că comanda nu există încă și fiecare va adăuga o înregistrare nouă.
Această situație se numește condiție de cursă. O simplă verificare prealabilă în cod nu protejează complet împotriva ei. Dezavantajul verificării fără o constrângere la nivelul bazei de date este că ea se defectează sub sarcină paralelă.
Comanda a fost înregistrată, dar răspunsul API s-a pierdut
Solicitarea trece prin mai multe etape: serverul primește datele, creează înregistrarea, pune sarcina în coadă, trimite răspunsul. O defecțiune este posibilă între oricare dintre ele. De exemplu, baza de date a confirmat deja crearea comenzii, dar conexiunea s-a întrerupt înainte de transmiterea răspunsului către client.
Clientul nu știe dacă comanda a fost acceptată și repetă operațiunea. API-ul fără un mecanism separat de verificare percepe solicitarea ca fiind nouă. În jurnal, acest lucru arată adesea ca și cum serviciul ar fi creat două comenzi „singur”, deși a avut două solicitări primite.
Cheia de idempotență pentru crearea comenzii
Pentru operațiunile de creare este nevoie de o cheie de idempotență unică. Clientul o generează înainte de prima trimitere și o transmite împreună cu parametrii comenzii. La repetare din cauza unui timeout sau a unei erori se folosește aceeași cheie.
API-ul salvează cheia împreună cu rezultatul procesării. Dacă sosește o solicitare cu o cheie deja cunoscută, serverul nu creează o comandă nouă, ci returnează rezultatul primei solicitări: identificatorul comenzii, starea acesteia sau eroarea generată anterior.
O cheie trebuie să corespundă unei singure operațiuni de business, nu unei singure conexiuni HTTP.
Dezavantajul metodei este că cheile trebuie stocate, curățate conform regulilor și verificate pe partea API. Dacă se generează o cheie nouă la fiecare repetare, protecția nu va funcționa. Dacă se folosește o singură cheie pentru comenzi diferite, o parte din operațiunile noi vor fi respinse din greșeală.

Unicitatea trebuie controlată de baza de date
Idempotența este mai bine să fie completată cu o constrângere de unicitate în baza de date. Pentru aceasta se alege o combinație care descrie fără ambiguitate comanda: identificatorul intern al clientului, cheia de idempotență, tipul serviciului și alte câmpuri necesare.
Baza de date trebuie să respingă a doua înregistrare, chiar dacă doi handler-i au ajuns la creare simultan. După conflict, API-ul returnează comanda existentă, nu o eroare fără explicații.
Dezavantajul unei constrângeri stricte de unicitate este că ea nu poate fi construită doar pe link sau username. Clientul poate comanda în mod deliberat același serviciu pentru același canal de mai multe ori. O constrângere prea largă va bloca achizițiile repetate normale.
Coada poate livra sarcina de mai multe ori
Coziile de sarcini funcționează adesea pe principiul „livrare cel puțin o dată”. Dacă un worker a procesat sarcina, dar nu a reușit să confirme finalizarea ei, coada poate emite aceeași sarcină din nou către un alt worker.
Pentru coadă acesta este un mod normal de a nu pierde sarcina. Pentru crearea comenzii fără idempotență — o sursă de duplicate. Identificatorul sarcinii sau o cheie separată a operațiunii trebuie transmise până la handler-ul final, inclusiv modulului de trimitere a comenzii către furnizor.
Dezavantajul dezactivării livrării repetate este că, la căderea unui worker, o parte din comenzi pot dispărea. Este mai sigur să accepți eventualele repetări și să faci handler-ul rezistent la ele.
Duplicatele apar între panou și furnizor
Comanda internă poate fi creată o singură dată, dar solicitarea către API-ul extern este trimisă de două ori. Cauza este aceeași: panoul nu a primit răspuns de la furnizor și a decis să retrimită. Dacă furnizorul a reușit să accepte prima solicitare, pe partea lui vor apărea două cereri identice.
Este nevoie de o legătură separată între comanda internă și cea externă: identificatorul trimiterii, cheia de idempotență sau răspunsul salvat al furnizorului. Nu se poate presupune că protecția la intrarea în propriul panou va proteja automat apelurile ieșite.
Dezavantajul reconcilierii cu un API terț este că nu fiecare furnizor acceptă căutarea după o cheie externă. Atunci trebuie să înregistrezi încercările de trimitere și să analizezi separat stările nedeterminate.
Webhook-ul nu trebuie să creeze o comandă nouă
Webhook-urile anunță modificări: comanda a fost acceptată, lansată, finalizată, anulată sau necesită verificare. Eroarea apare atunci când handler-ul webhook-ului percepe notificarea ca pe o comandă de a crea din nou comanda.
Același webhook poate sosi repetat. Expeditorul repetă livrarea dacă nu a primit confirmare, iar notificările uneori sosesc în ordine greșită. Handler-ul trebuie să găsească comanda existentă după identificatorul extern și să actualizeze starea.
Dezavantajul procesării webhook-urilor doar după momentul primirii este că o notificare tardivă poate suprascrie starea actuală cu una depășită. Sunt necesare identificatorul evenimentului, versiunea stării sau reguli clare de tranziție.
Ce înregistrări ajută la găsirea sursei duplicatelor
Pentru investigație nu este suficient să vezi doar două numere de comandă. Sunt necesare date despre fiecare etapă de procesare: momentul solicitării, cheia de idempotență, identificatorul clientului, parametrii comenzii, numărul sarcinii din fundal, răspunsul API-ului extern și încercările de retrimitere.
- corelează duplicatele după cheia operațiunii, nu doar după link;
- verifică dacă au existat solicitări identice în jurnalul API-ului de intrare;
- verifică dacă sarcina a fost repetată în coadă;
- separă crearea comenzii interne de trimiterea către furnizor;
- salvează identificatorul extern al cererii imediat după primirea răspunsului.
Dezavantajul jurnalelor prea scurte este că sursa problemei dispare înainte de a fi analizată. Dezavantajul logării excesive este că în înregistrare pot ajunge token-uri, date personale și alte câmpuri sensibile, așa că acestea trebuie mascate.
Cum se procesează un rezultat nedeterminat al solicitării
După un timeout nu se poate crea imediat comanda din nou cu date noi. Mai întâi API-ul trebuie să verifice operațiunea după cheia de idempotență sau după identificatorul clientului. Dacă comanda este găsită, se returnează starea ei actuală. Dacă procesarea încă are loc, clientul primește o stare de așteptare.
- Creează cheia operațiunii înainte de prima solicitare.
- Trimite aceeași cheie la fiecare repetare.
- Salvează cheia și comanda într-o singură operațiune protejată a bazei de date.
- Transmite identificatorul operațiunii către coadă și API-ul extern.
- Returnează comanda creată anterior la o solicitare repetată.
Un astfel de scenariu necesită îmbunătățirea API-ului și a integrării clientului. Dezavantajul lui este depanarea mai complexă și mai multe stări ale comenzii, însă livrarea repetată a solicitării nu mai înseamnă automat o achiziție repetată.
Last Articles
Ce s-a schimbat în design și funcționalitate Am actualizat site-ul pentru a lucra cu el mai rapid și mai comod. Principalele modificări vizează inter..
Good afternoon, I've collected all the news during this time.: 1. The main news is that prices for twitch viewers have been greatly reduced, while Tw..
1. Folosiți codul promoțional "December2025" pentru o reducere de 15% pentru toți spectatorii noștri2. Am redus până la 1 ianuarie prețurile de bază p..
Serviciile Twitch sunt lucrând stabil, așa că suntem gata să cooperăm cu Echipe, revânzători, proprietari de servicii, proprietari de bot și mulți..
Noi au actualizat complet serviciile noastre Twitch viewer și acum sunt lucrează stabil. Folosim doar adrese IP de înaltă calitate pentru spectato..
Hello everyone! Today, we are announcing a new feature—"Twitch Viewer Configurator". Now, you can customize any plan for your Twitch channel. Choo..
Greetings, I have compiled a guide for streamers, which will be very relevant at the moment. Now YouTube and twitch have disabled monetization from vi..
We have finally developed the APINow it will be more convenient for our partner sites to work with us.To update the maximum tariffs for YouTube, an up..
Datorită popularității uriașe a serviciilor de parteneriat și programului de recomandare, am realizat o masă de cooperare. Esența este foarte simplă: ..
Serviciile noastre pentru streameri

Shopee
Serviciile noastre pentru creatorii de conținut









