Idempotency näme?
Salam dostlar!
Internetde bir zat satyn alanyňda "Töle" düwmesine basdyň welin, sahypa doňup galdy. Näme etmeli? Ýene basýarsyň. Ýene doňdy. Ýene basýarsyň. Soň bank hasabyňa seretseň üç gezek pul çekildi! 😱
Ine, şu betbagtçylygyň öňüni alýan zada idempotency diýilýär. Geliň, muny ýönekeý dilde, ýerden düşündireýin.
Idempotency näme?
Sözlük manysy biraz gorkunç eşidilýär, ýöne aňyrsynda örän ýönekeý pikir bar:
Idempotency — bir amaly bir gezek ýerine ýetireniň bilen köp gezek ýerine ýetireniň arasynda netije taýdan tapawut ýok diýmekdir.
Ýagny, sen şol bir zady 1 gezek etseň-de, 100 gezek etseň-de — ahyrky netije birmeňzeş bolýar.
Gündelik durmuşdan mysal berelin:
- Lift düwmesi: Lifti çagyrmak üçin düwmä bir gezek basdyň. Ýene 10 gezek bassaň näme üýtgeýär? Hiç zat! Lift birje gezek gelýär. Bu idempotent amal.
- Otag çyrasyny öçürmek: Öçük çyranyň açaryny ýene "öçür" tarapa itseň, çyra öçükligine galýar. Netije üýtgemeýär.
Emma:
- Lifte adam mündürmek: Her gezek "mün" diýseň, ýene bir adam girýär. Bu idempotent däl — her amal ýagdaýy üýtgedýär.
Gördüňizmi? Idempotency diýmek "gaýtalamak howpsuz" diýmek.
Näme üçin bu backend-de şeýle möhüm?
Internet ynamdar däl ýer. Set (network) käwagt üzülýär, request ýolda ýitýär, ýa-da jogap gijä galýar. Meselä seredeliň:
- Ulanyjy "Töle" düwmesine basýar → serwere request gidýär.
- Serwer puly alýar, ýazgy edýär... ýöne jogaby ulanyja gaýdyp gelmeýär (set üzüldi).
- Ulanyjy: "Hmm, işlemedimikä?" diýip ýene basýar.
- Serwer ikinji requesti hem täze töleg hökmünde kabul edýär → iki gezek pul çykýar!
Şu ýerde iki tarap hem günäkär däl — set näsaz işledi. Emma netije agyr. Idempotency edil şu problemany çözýär.
Ynamdar sistema — request ýitip gitse-de, gaýtalansa-da, dogry işlemeli. Idempotency şonuň esasy diregi.
HTTP metodlary we idempotency
Gyzykly ýeri: HTTP protokolynyň özi käbir metodlary eýýäm idempotent diýip belleýär. Geliň, tablisada göreliň:
| Metod | Idempotentmi? | Näme edýär |
|---|---|---|
| GET | ✅ Hawa | Diňe maglumat okaýar, üýtgetmeýär |
| PUT | ✅ Hawa | Resursy doly çalyşýar (üstüne ýazýar) |
| DELETE | ✅ Hawa | Pozýar (eýýäm pozulan bolsa, üýtgemeýär) |
| POST | ❌ Ýok | Her gezek täze zat döredýär |
PUT näme üçin idempotent? Sebäbi ol "bu resurs indi şeýle bolsun" diýýär. On gezek şol bir maglumat bilen PUT etseň, resurs şol bir ýagdaýda galýar.
POST näme üçin idempotent däl? Sebäbi ol "täze zat döret" diýýär. Her gezek täze ýazgy, täze töleg, täze order döreýär. Ine, biziň ýokardaky "üç gezek pul çykdy" problemamyz hut şu POST-dan gelip çykýar!
Onda POST-y nädip howpsuz edýäris? Idempotency Key!
Çözgüt örän ýönekeý we owadan: Idempotency Key (idempotentlik açary).
Pikir şeýle: her requeste ulanyjy tarapyndan ýeke-täk (unique) belgi dakylýar. Serwer şol belgini ýatda saklaýar. Eger şol bir belgi bilen ýene request gelse, serwer täze amal etmän, öňki netijäni gaýtaryp berýär.
Restoran mysalyny göz öňüne getir:
- Sen ofisianta zakaz berdiň, ol saňa çek belgisi berdi:
#A-42. - Internet üzüldi, sen "zakazym gitdimikä?" diýip ofisianta ýene şol
#A-42belgi bilen ýüzlendiň. - Ofisiant: "Bu zakaz eýýäm bar, ynha taýýarlanýar" diýýär. Iki sapar şol bir nahar bişirmeýär!
Kod tarapynda akym şeýle bolýar:
1. Klient unique key döredýär (mysal: UUID)
2. Request-i şol key bilen iberýär (header-de: Idempotency-Key)
3. Serwer barlaýar: bu key öň görlüpmi?
- ÝOK => amaly ýerine ýetir, netijäni key bilen sakla, jogap ber
- HAWA => täze amal etme, saklanan netijäni gaýtaryp ber
Praktikada request şuňa meňzeş görünýär:
POST /payments HTTP/1.1
Host: api.example.com
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json
{
"amount": 100,
"currency": "TMT"
}
Indi ulanyjy näçe gezek bassada, şol bir Idempotency-Key gidýär we serwer diňe bir gezek pul çykarýar. Problema çözüldi!
Stripe, PayPal ýaly uly töleg sistemalary hut şu usuly ulanýar. Sen olaryň API-syna töleg iberеňde, hökman
Idempotency-Keyiberýärsiň.
Serwer tarapynda näme bolýar?
Serwer bu key-leri bir ýerde saklamaly. Adatça Redis ýa-da maglumat bazasy ulanylýar. Ýönekeý logika:
public PaymentResult processPayment(String idempotencyKey, PaymentRequest request) {
// 1. Bu key öň görlüpmi?
PaymentResult existing = cache.get(idempotencyKey);
if (existing != null) {
return existing; // Öňki netijäni gaýtar, täze amal etme!
}
// 2. Ilkinji gezek: tölegi ýerine ýetir
PaymentResult result = paymentService.charge(request);
// 3. Netijäni key bilen sakla (mysal: 24 sagatlyk)
cache.set(idempotencyKey, result, Duration.ofHours(24));
return result;
}
Üns beriň — key-leri hemişelik saklamak zerur däl. Adatça belli bir wagt (mysal, 24 sagat) saklanýar, soň öçürilýär. Çünki ulanyjy 3 günden soň şol bir düwmä basmaýar.
Ünsden düşürilmeli birnäçe nokat
Idempotency-ni durmuşa geçireniňde şulara üns ber:
- Key-i klient döretmeli: Serwer däl, klient (mysal: brauzer ýa-da mobil programma) unique key döretmeli. Sebäbi eger set üzülip, ulanyjy "täzeden bassа", şol bir key ulanylmaly.
- Race condition: Iki request birbada gelse näme? Bu ýerde lock (gulp) ýa-da atomic amal gerek, ýogsam ikisi hem "täze" diýip düşünäýmegi mümkin.
Netije
Idempotency ilki bada çylşyrymly söz ýaly eşidilýär, ýöne aňyrsynda örän ynsana ýakyn pikir bar: "Bir zady birnäçe gezek gaýtalasaň-da, hiç zat döwülmesin."
Bu diňe töleg sistemalary üçin däl. Islendik ynamdar backend gurjak bolsaň — order sistemasy, email ibermek, maglumat sinhronizasiýasy — idempotency ulanmak iň gowy karar bolar. Set üzüler, request gaýtalanаr, ulanyjy düwmä on gezek basar. Emma seniň sistemаň asuda we dogry işläp durar.
Coding happy, dostlar!
(Gramatika we käbir söz düzetmeleri üçin AI ulandym).