Nordlet

← दस्तावेज़ / शब्दकोश

आइडempotency क्या है? अकाउंटिंग और पेमेंट API के लिए इसकी आवश्यकता क्यों है

जानें कि कैसे एक रीट्राई किया गया अनुरोध (request) एक डुप्लीकेट इनवॉइस बनाता है, एक आइडempotency की क्या गारंटी देती है, किन विफलता मोडों (failure modes) को इसे संभालना चाहिए, और इसे सही तरीके से कैसे लागू करें।

कोई ऑपरेशन तब आइडempotent (idempotent) होता है जब उसे दो बार निष्पादित करने का प्रभाव उसे एक बार करने के समान होता है। किसी रिकॉर्ड को पढ़ना (read) स्वभाव से आइडempotent होता है। इनवॉइस बनाना ऐसा नहीं है - इसे दो बार कॉल करें और आपके पास दो इनवॉइस, दो प्राप्य (receivables) और एक ग्राहक होगा जो पूछेगा कि उससे दो बार बिल क्यों लिया गया है।

यह अंतर महत्वपूर्ण है क्योंकि नेटवर्क एक विशिष्ट और बुरी तरह से विफल होते हैं: अनुरोध सफल हो जाता है और प्रतिक्रिया (response) खो जाती है। क्लाइंट को टाइमआउट दिखाई देता है और वह यह अंतर नहीं कर पाता कि अनुरोध "कभी नहीं पहुँचा" या "पहुँच गया, काम कर गया, उत्तर खो गया"। इसका एकमात्र सुरक्षित दिखने वाला विकल्प रीट्राई (retry) करना है, और रीट्राई ही वह चीज़ है जो डुप्लीकेट बनाती है।

अकाउंटिंग इसे और बदतर क्यों बनाती है

अधिकांश सिस्टम में डुप्लीकेट होना एक झुंझलाहट मात्र है। लेज़र में यह एक बढ़ता हुआ संकट है:

  • एक डुप्लीकेट इनवॉइस गैपलेस सीक्वेंस (gapless sequence) से एक नंबर की खपत करता है, इसलिए इसे हटाना कोई विकल्प नहीं है - इम्यूटेबिलिटी (immutability) का मतलब है कि इसे सुधारने के लिए क्रेडिट नोट की आवश्यकता होती है, जो एक ऐसा दस्तावेज़ है जिसे आपका ग्राहक देखता है।
  • डुप्लीकेट जर्नल प्रविष्टियाँ (journal entries) पोस्ट करता है, इसलिए जब तक किसी का ध्यान नहीं जाता, तब तक रेवेन्यू, वैट (VAT) और प्राप्य (receivables) सभी बढ़े हुए दिखते हैं।
  • यह वैट रिटर्न (VAT return) और लिथुआनिया में i.SAF रजिस्टरों में प्रवेश करता है।
  • यदि इसने भुगतान (payment) को ट्रिगर किया है, तो वास्तव में पैसे का लेन-देन हो चुका है।

"बस डुप्लीकेट की जाँच करें" यह तरीका भी काम नहीं करता है, क्योंकि एक ही दिन एक ही राशि के लिए एक ही ग्राहक को दो वास्तव में अलग-अलग इनवॉइस पूरी तरह से सामान्य हैं। सिस्टम सामग्री से इरादे का अनुमान नहीं लगा सकता - क्लाइंट को इसे स्पष्ट करना होगा।

आइडempotency की काम कैसे करती हैं

क्लाइंट प्रत्येक लॉजिकल ऑपरेशन के लिए एक यूनीक की (key) जनरेट करता है और उसे अनुरोध के साथ भेजता है:

POST /v1/sales/invoices/create
Idempotency-Key: 8f14e45f-ea1b-4c2b-9f3a-2d7c1e0b5a91

इसके बाद सर्वर यह गारंटी देता है:

  1. इस की के साथ पहला अनुरोध - सामान्य रूप से प्रोसेस करें, की के विरुद्ध परिणाम को स्टोर करें।
  2. समान की और समान पेलोड (payload) के साथ रीट्राई - दोबारा निष्पादित न करें; संग्रहीत प्रतिक्रिया (stored response) लौटाएँ।
  3. समान की, अलग पेलोड - अस्वीकार करें। की यह दावा करती है कि यह वही ऑपरेशन है; एक अलग बॉडी का मतलब है कि यह वह नहीं है, और चुपचाप पुराना परिणाम लौटाना त्रुटि से भी बदतर होगा।
  4. मूल अनुरोध के अभी भी चलते रहने के दौरान रीट्राई - समवर्ती (concurrently) रूप से निष्पादित होने के बजाय रीट्राई करने योग्य त्रुटि के साथ अस्वीकार करें।

चौथा बिंदु वह है जिसे साधारण इम्प्लीमेंटेशन अक्सर छोड़ देते हैं। एक क्लाइंट जो 5 सेकंड पर टाइमआउट होता है और 6 पर रीट्राई करता है, वह अपने खुद के इन-फ्लाइट (in-flight) अनुरोध से टकराएगा; कॉन्करेंसी गार्ड के बिना, दोनों आगे बढ़ते हैं और आपको वह डुप्लीकेट मिल जाता है जिसे रोकने के लिए यह तंत्र मौजूद था।

की को सही तरीके से जनरेट करना

की को प्रयास (attempt) के बजाय ऑपरेशन की पहचान करनी चाहिए:

  • सही: जब उपयोगकर्ता "इनवॉइस जारी करें" पर क्लिक करता है, तो एक बार जनरेट किया गया UUID, उस क्लिक के हर रीट्राई के लिए दोबारा इस्तेमाल किया जाता है।
  • सही: आपके अपने डोमेन से ली गई एक निश्चित की - order-1041-invoice।
  • गलत: प्रत्येक HTTP प्रयास के लिए एक नया UUID। हर रीट्राई को एक नया की मिलता है, इसलिए हर रीट्राई एक नया ऑपरेशन है, और आपने कुछ भी लागू नहीं किया है।
  • गलत: पेलोड का हैश (hash)। दो कानूनी रूप से समान ऑपरेशन तब आपस में टकराते हैं, और दूसरे को चुपचाप दबा दिया जाता है।

कीज़ को एक रिटेंशन अवधि की आवश्यकता होती है - वास्तविक रीट्राई विंडो और क्लाइंट आउटेज को कवर करने के लिए पर्याप्त लंबी, हमेशा के लिए नहीं।

यह किस समस्या का समाधान नहीं करता है

आइडempotency एक ही अनुरोध के डुप्लीकेट निष्पादन से सुरक्षा करती है। यह इनसे सुरक्षा नहीं करती है:

  • अलग-अलग सत्रों (sessions) से एक ही इनवॉइस बनाने वाले दो अलग-अलग उपयोगकर्ता - यह एक व्यावसायिक-नियम (business-rule) की समस्या है, जिसे यूनीकनेस बाधाओं जैसे कि प्रति ऑर्डर एक इनवॉइस द्वारा हल किया जाता है।
  • अलग-अलग कीज़ वाले लॉजिकल डुप्लीकेट्स।
  • ऑपरेशन के भीतर गैर-निश्चितता (non-determinism) - यदि हैंडलर टाइमस्टैंप या नंबर जनरेट करता है, तो संग्रहीत प्रतिक्रिया पहले वाले को कैप्चर करती है, जो कि वांछित व्यवहार है लेकिन जिसे समझना उपयोगी है।

यह डेटाबेस बाधाओं को प्रतिस्थापित करने के बजाय उनके साथ जोड़ी बनाती है। Nordlet का लेज़र दोनों का उपयोग करता है: आइडempotency कीज़ रीट्राई किए गए अनुरोधों को रोकती हैं, जबकि यूनीक इंडेक्स भुगतान आईडी प्रति डुप्लीकेट सेटलमेंट बैच, आपूर्तिकर्ता और दस्तावेज़ संख्या प्रति डुप्लीकेट खरीद इनवॉइस, और परिसंपत्ति और अवधि प्रति डुप्लीकेट मूल्यह्रास रन को रोकते हैं।

Nordlet इसे कैसे लागू करता है

स्टेट-बदलने वाले किसी भी अनुरोध पर Idempotency-Key हेडर भेजें - जो अधिकतम 255 वर्णों की एक गैर-खाली स्ट्रिंग हो।

दी गई की के साथ पहला अनुरोध निष्पादित होता है और उसका परिणाम स्टोर हो जाता है। समान की और समान पेलोड के साथ रीट्राई कॉल को जितनी बार चाहें उतनी बार दोहराए जाने के बावजूद, बिना दोबारा निष्पादित किए संग्रहीत प्रतिक्रिया को लौटाता है, जिससे इनवॉइस ठीक एक बार बनता है।

दो विफलता मोड (failure modes) चुपचाप होने के बजाय स्पष्ट किए गए हैं:

  • समान की, अलग पेलोड → अस्वीकार कर दिया गया: "Idempotency-Key का उपयोग पहले ही एक अलग अनुरोध पेलोड के साथ किया जा चुका है।" यह उस खतरनाक मामले को पकड़ता है जहाँ कोई क्लाइंट राशि बदलते समय की का पुन उपयोग करता है।
  • समान की, मूल अनुरोध अभी भी प्रोसेस हो रहा है → रीट्राई करने योग्य के रूप में अस्वीकार किया गया: "इस Idempotency-Key वाला अनुरोध अभी भी प्रोसेस किया जा रहा है, कृपया थोड़ी देर बाद रीट्राई करें।" कोई समवर्ती डबल-निष्पादन (concurrent double-execution) नहीं।

कीज़ प्रति कंपनी के दायरे में होती हैं, इसलिए एक ही UUID जनरेट करने वाले दो टेनेंट कभी नहीं टकराते हैं।

पूरक गारंटी (complementary guarantee) दूसरी दिशा में चलती है। वेबहुक डिलीवरी कम से कम एक बार (at-least-once) होती है, जिसका अर्थ है कि आपका समापन बिंदु (endpoint) कभी-कभार एक ही घटना को दो बार प्राप्त करेगा - उस टाइमआउट के बाद जहाँ डिलीवरी वास्तव में सफल रही, या पुनर्वितरण पर। प्रत्येक घटना में एक आईडी होती है, और आपके हैंडलर को प्रोसेस की गई आईडी को रिकॉर्ड करना चाहिए और दोहराव को अनदेखा करना चाहिए। आइडempotency एक ऐसी विशेषता है जिसकी एक इंटीग्रेशन के दोनों पक्षों को आवश्यकता होती है; API परंपराएँ मार्गदर्शिका अनुरोध पक्ष को विस्तार से कवर करती है।

FAQ

आइडempotency की क्या है?

एक क्लाइंट द्वारा जनरेट किया गया आइडेंटिफ़ायर जो अनुरोध के साथ भेजा जाता है जो सर्वर को एक ही लॉजिकल ऑपरेशन के रीट्राई को पहचानने की अनुमति देता है। पहला अनुरोध निष्पादित होता है; समान की के साथ रीट्राई फिर से निष्पादित होने के बजाय संग्रहीत परिणाम लौटाते हैं।

अकाउंटिंग API को आइडempotency की आवश्यकता क्यों है?

क्योंकि एक डुप्लीकेट राइट वास्तविक परिणामों के साथ एक वास्तविक दस्तावेज़ बनाता है - एक अनुक्रमिक संख्या की खपत करने वाला दूसरा इनवॉइस, लेज़र में पोस्ट करना, और वैट रिटर्न में प्रवेश करना। एक डुप्लीकेट रीड के विपरीत, इसे बस हटाया नहीं जा सकता; इसे क्रेडिट नोट के साथ सुधारा जाना चाहिए।

क्या मुझे प्रत्येक रीट्राई के लिए एक नया की जनरेट करना चाहिए?

नहीं - यह तंत्र को पूरी तरह से विफल कर देता है। प्रत्येक लॉजिकल ऑपरेशन के लिए एक की जनरेट करें और उस ऑपरेशन के हर रीट्राई के लिए उसका पुन उपयोग करें। प्रत्येक प्रयास के लिए एक नया की मतलब है कि हर प्रयास को एक नए ऑपरेशन के रूप में माना जाता है।

यदि मैं अलग पेलोड के साथ किसी की का पुन उपयोग करता हूँ तो क्या होता है?

अनुरोध अस्वीकार कर दिया जाता है। की यह दावा करती है कि यह वही ऑपरेशन है, इसलिए बदली हुई बॉडी का मतलब है कि कुछ गड़बड़ है - सबसे अधिक संभावना क्लाइंट पर की-पुन उपयोग (key-reuse) बग की है। चुपचाप पहले का परिणाम लौटाना बदतर होगा।

क्या आइडempotency सभी डुप्लीकेट्स को रोकती है?

नहीं। यह एक ही अनुरोध के डुप्लीकेट निष्पादन को रोकता है। स्वतंत्र रूप से एक ही इनवॉइस बनाने वाले दो अलग-अलग उपयोगकर्ताओं ने दो अलग-अलग अनुरोध किए हैं, जो यूनीकनेस बाधाओं के लिए एक व्यावसायिक-नियम की समस्या है, न कि कोई ऐसी चीज़ जिसे आइडempotency की देख सके।