टीएल; डीआर: नीचे दिए गए प्रश्न नीचे उबलते हैं: जब एक पंक्ति सम्मिलित करते हैं, तो एक नए मूल्य की पीढ़ीIdentity
और क्लस्टर इंडेक्स में संबंधित पंक्ति कुंजी के लॉक होने के बीच अवसर की एक खिड़की होती है, जहां एक बाहरी पर्यवेक्षक एक नया देख सकता है। Identity
समवर्ती लेनदेन द्वारा डाला गया मूल्य? (SQL सर्वर में।)
विस्तृत संस्करण
मेरे पास एक Identity
कॉलम के साथ एक SQL सर्वर टेबल है CheckpointSequence
, जो टेबल के क्लस्टर इंडेक्स की कुंजी है (जिसमें कई अतिरिक्त गैर-अनुक्रमित इंडेक्स भी हैं)। पंक्तियों को कई समवर्ती प्रक्रियाओं और थ्रेड्स (अलगाव स्तर पर , और बिना ) द्वारा तालिका में डाला जाता है । उसी समय, उस कॉलम द्वारा आदेशित क्लस्टर इंडेक्स से समय-समय पर पंक्तियों को पढ़ने की प्रक्रिया होती है, (अलगाव स्तर पर , विकल्प बंद होने के साथ )।READ COMMITTED
IDENTITY_INSERT
CheckpointSequence
READ COMMITTED
READ COMMITTED SNAPSHOT
मैं वर्तमान में इस तथ्य पर भरोसा करता हूं कि पढ़ने की प्रक्रिया कभी भी एक चेकपॉइंट को "छोड़" नहीं सकती है। मेरा सवाल है: क्या मैं इस संपत्ति पर भरोसा कर सकता हूं? और अगर नहीं, तो मैं इसे सच करने के लिए क्या कर सकता था?
उदाहरण: जब पहचान मान 1, 2, 3, 4, और 5 वाली पंक्तियों को डाला जाता है, तो पाठक को मान 5 के साथ देखने से पहले पंक्ति 5 को नहीं देखना चाहिए । परीक्षण से पता चलता है कि क्वेरी, जिसमें एक ORDER BY CheckpointSequence
खंड है ( और एक WHERE CheckpointSequence > -1
खंड), जब भी पंक्ति 4 को पढ़ना है, तो विश्वसनीय रूप से ब्लॉक करता है, लेकिन अभी तक प्रतिबद्ध नहीं है, भले ही पंक्ति 5 पहले से ही प्रतिबद्ध हो।
मेरा मानना है कि कम से कम सिद्धांत रूप में, यहां एक दौड़ की स्थिति हो सकती है जो इस धारणा को तोड़ सकती है। दुर्भाग्य से, दस्तावेज़ीकरण कई समवर्ती लेनदेन के संदर्भ में Identity
कैसे Identity
काम करता है, इसके बारे में बहुत कुछ नहीं कहता है , यह केवल कहता है "प्रत्येक नया मूल्य वर्तमान बीज और वेतन वृद्धि के आधार पर उत्पन्न होता है।" और "किसी विशेष लेनदेन के लिए प्रत्येक नया मूल्य तालिका के अन्य समवर्ती लेनदेन से अलग है।" ( MSDN )
मेरा तर्क है, यह किसी तरह काम करना चाहिए:
- एक लेन-देन शुरू किया जाता है (या तो स्पष्ट रूप से या अंतर्निहित रूप से)।
- एक पहचान मूल्य (X) उत्पन्न होता है।
- पहचान मूल्य के आधार पर क्लस्टर इंडेक्स पर संबंधित पंक्ति लॉक लिया जाता है (जब तक कि लॉक एस्केलेशन अंदर न हो जाए, जिस स्थिति में पूरी टेबल लॉक हो जाती है)।
- पंक्ति डाली गई है।
- लेनदेन प्रतिबद्ध है (संभवतः बाद में काफी समय), इसलिए ताला फिर से हटा दिया जाता है।
मुझे लगता है कि चरण 2 और 3 के बीच, एक बहुत छोटी खिड़की है जहां
- एक समवर्ती सत्र अगले पहचान मूल्य (X + 1) उत्पन्न कर सकता है और सभी शेष चरणों को निष्पादित कर सकता है,
- इस प्रकार एक पाठक को उस समय के मूल्य X + 1 को पढ़ने की अनुमति देता है, जिससे X का मान गायब हो जाता है।
बेशक, इस की संभावना बेहद कम लगती है; लेकिन फिर भी - ऐसा हो सकता है। या कर सकता था?
(यदि आप संदर्भ में रुचि रखते हैं: यह NEventStore के एसक्यूएल पर्सिस्टेंस इंजन का कार्यान्वयन है। NEventStore एपेंड-ओनली इवेंट स्टोर पर लागू होता है, जहां हर ईवेंट को एक नया, आरोही चेकपॉइंट अनुक्रम संख्या मिलती है। ग्राहक चेकपॉइंट द्वारा ऑर्डर किए गए इवेंट स्टोर से घटनाओं को पढ़ते हैं। सभी प्रकार की संगणनाएँ करने के लिए। एक बार जब चेकपॉइंट X के साथ कोई घटना संसाधित हो जाती है, तो ग्राहक केवल "नई" घटनाओं पर विचार करते हैं, यानी, चेकपॉइंट X + 1 और इसके बाद की घटनाओं के साथ। इसलिए, यह महत्वपूर्ण है कि घटनाओं को कभी भी छोड़ा नहीं जा सकता है, जैसा कि उन्हें फिर से कभी नहीं माना जाएगा। मैं वर्तमान में यह निर्धारित करने की कोशिश कर रहा हूं कि Identity
-बेड चेकपॉइंट कार्यान्वयन इस आवश्यकता को पूरा करता है। ये उपयोग किए गए सटीक एसक्यूएल बयान हैं : स्कीमा , राइटर की क्वेरी ,रीडर की क्वेरी ।)
यदि मैं सही हूं और ऊपर वर्णित स्थिति उत्पन्न हो सकती है, तो मैं उनके साथ निपटने के केवल दो विकल्प देख सकता हूं, दोनों ही असंतोषजनक हैं:
- X को देखने से पहले चेकपॉइंट अनुक्रम मान X + 1 को देखते समय, X + 1 को खारिज कर दें और बाद में पुनः प्रयास करें। हालाँकि, क्योंकि
Identity
निश्चित रूप से अंतराल उत्पन्न कर सकते हैं (उदाहरण के लिए, जब लेन-देन वापस ले लिया जाता है), एक्स कभी नहीं आ सकता है। - तो, एक ही दृष्टिकोण, लेकिन n मिलीसेकंड के बाद अंतर को स्वीकार करें। हालाँकि, मुझे n का क्या मान लेना चाहिए?
कोई बेहतर विचार?