कोई भी प्रोग्रामर आपको बताएगा कि सुरक्षित मल्टी-थ्रेडेड कोड लिखना कठिन हो सकता है। इसमें शामिल तकनीकी मुद्दों की बहुत देखभाल और अच्छी समझ की आवश्यकता है। एक डेटाबेस व्यक्ति के रूप में, आप सोच सकते हैं कि टी-एसक्यूएल लिखते समय इस प्रकार की कठिनाइयाँ और जटिलताएँ लागू नहीं होती हैं। इसलिए, यह महसूस करना एक झटके के रूप में आ सकता है कि टी-एसक्यूएल कोड भी दौड़ की स्थिति और अन्य डेटा अखंडता जोखिमों के प्रति संवेदनशील है जो आमतौर पर बहु-थ्रेडेड प्रोग्रामिंग से जुड़े होते हैं। यह सच है कि हम एक टी-एसक्यूएल स्टेटमेंट के बारे में बात कर रहे हैं, या एक स्पष्ट लेनदेन में संलग्न बयानों के समूह के बारे में बात कर रहे हैं।
इस मुद्दे के केंद्र में यह तथ्य है कि डेटाबेस सिस्टम एक ही समय में कई लेनदेन को निष्पादित करने की अनुमति देता है। यह एक प्रसिद्ध (और बहुत ही वांछनीय) मामलों की स्थिति है, फिर भी उत्पादन का एक बड़ा सौदा टी-एसक्यूएल कोड अभी भी चुपचाप मानता है कि लेनदेन के निष्पादन के दौरान अंतर्निहित डेटा नहीं बदलता है या एक डीएमएल स्टेटमेंट जैसे SELECT
, INSERT
, UPDATE
, DELETE
, या MERGE
।
यहां तक कि जहां कोड लेखक समवर्ती डेटा परिवर्तनों के संभावित प्रभावों से अवगत है, स्पष्ट लेनदेन का उपयोग अक्सर अधिक सुरक्षा प्रदान करने के लिए माना जाता है जो वास्तव में उचित है। ये धारणाएँ और गलत धारणाएँ सूक्ष्म हो सकती हैं, और निश्चित रूप से अनुभवी डेटाबेस प्रैक्टिशनर्स को भी गुमराह करने में सक्षम हैं।
अब, ऐसे मामले हैं जहां ये मुद्दे व्यावहारिक अर्थों में ज्यादा मायने नहीं रखेंगे। उदाहरण के लिए, डेटाबेस केवल-पढ़ने के लिए हो सकता है, या कोई अन्य वास्तविक गारंटी . हो सकती है कि जब हम इसके साथ काम कर रहे हों तो कोई और अंतर्निहित डेटा को नहीं बदलेगा। समान रूप से, विचाराधीन ऑपरेशन आवश्यकता . नहीं हो सकता है परिणाम जो बिल्कुल . हैं सही; हमारे डेटा उपभोक्ता अनुमानित परिणाम से पूरी तरह से खुश हो सकते हैं (यहां तक कि वह भी जो किसी भी पर डेटाबेस की प्रतिबद्ध स्थिति का प्रतिनिधित्व नहीं करता है) समय पर)।
समवर्ती समस्याएं
समवर्ती रूप से निष्पादित कार्यों के बीच हस्तक्षेप का प्रश्न प्रोग्रामिंग भाषाओं जैसे सी # या जावा में काम करने वाले एप्लिकेशन डेवलपर्स के लिए एक परिचित समस्या है। समाधान कई और विविध हैं, लेकिन आम तौर पर परमाणु संचालन . का उपयोग करना शामिल है या परस्पर-अनन्य संसाधन प्राप्त करना (जैसे लॉक ) जबकि एक संवेदनशील ऑपरेशन जारी है। जहां उचित सावधानी नहीं बरती जाती है, संभावित परिणाम दूषित डेटा, एक त्रुटि, या शायद एक पूर्ण दुर्घटना भी हो सकते हैं।
कई समान अवधारणाएं (जैसे परमाणु संचालन और ताले) डेटाबेस की दुनिया में मौजूद हैं, लेकिन दुर्भाग्य से उनमें अक्सर अर्थ में महत्वपूर्ण अंतर होते हैं। . अधिकांश डेटाबेस लोग डेटाबेस लेनदेन के ACID गुणों से अवगत हैं, जहां A का अर्थ परमाणु . है . SQL सर्वर लॉक का भी उपयोग करता है (और आंतरिक रूप से अन्य पारस्परिक-बहिष्करण उपकरण)। इनमें से किसी भी शब्द का मतलब उतना नहीं है जितना एक अनुभवी C# या Java प्रोग्रामर यथोचित रूप से अपेक्षा करता है, और कई डेटाबेस पेशेवरों को इन विषयों की एक भ्रमित समझ भी होती है (जैसा कि आपके पसंदीदा खोज इंजन का उपयोग करके एक त्वरित खोज गवाही देगी)।
दोहराने के लिए, कभी-कभी ये मुद्दे व्यावहारिक चिंता का विषय नहीं होंगे। यदि आप डेटाबेस सिस्टम में सक्रिय आदेशों की संख्या की गणना करने के लिए एक प्रश्न लिखते हैं, तो यह कितना महत्वपूर्ण है यदि गिनती थोड़ी दूर हो? या अगर यह किसी अन्य समय में डेटाबेस की स्थिति को दर्शाता है?
वास्तविक प्रणालियों के लिए समवर्ती और संगति के बीच एक व्यापार-बंद करना आम बात है (भले ही उस समय डिजाइनर को इसके बारे में पता न हो - सूचित व्यापार-बंद शायद एक दुर्लभ जानवर हैं)। वास्तविक सिस्टम अक्सर पर्याप्त रूप से काम करते हैं , किसी भी विसंगति के साथ अल्पकालिक या महत्वहीन माना जाता है। वेब पेज पर असंगत स्थिति देखने वाला उपयोगकर्ता अक्सर पेज को रीफ्रेश करके समस्या का समाधान करेगा। यदि समस्या की रिपोर्ट की जाती है, तो संभवतः इसे प्रतिलिपि प्रस्तुत करने योग्य नहीं के रूप में बंद कर दिया जाएगा। मैं यह नहीं कह रहा हूं कि यह एक वांछनीय स्थिति है, बस यह मानते हुए कि ऐसा होता है।
फिर भी, बुनियादी स्तर पर समवर्ती मुद्दों को समझना बहुत उपयोगी है। उनके बारे में जागरूक होना हमें सही (या सूचित .) लिखने में सक्षम बनाता है सही-पर्याप्त) परिस्थितियों के अनुसार टी-एसक्यूएल। इससे भी महत्वपूर्ण बात यह है कि यह हमें टी-एसक्यूएल लिखने से बचने की अनुमति देता है जो हमारे डेटा की तार्किक अखंडता से समझौता कर सकता है।
लेकिन, SQL सर्वर ACID गारंटी प्रदान करता है!
हां, ऐसा होता है, लेकिन वे हमेशा आपकी अपेक्षा के अनुरूप नहीं होते हैं, और वे हर चीज की रक्षा नहीं करते हैं। अधिक बार नहीं, मनुष्य ACID . में कहीं अधिक पढ़ते हैं की तुलना में उचित है।
एसीआईडी संक्षिप्त शब्द के सबसे अक्सर गलत समझे जाने वाले घटक परमाणु, संगत और पृथक शब्द हैं - हम एक पल में उनके पास आएंगे। दूसरा वाला, टिकाऊ , पर्याप्त सहज ज्ञान युक्त है जब तक आपको याद है कि यह केवल स्थायी . पर लागू होता है (वसूली योग्य) उपयोगकर्ता डेटा।
उस सब के साथ, SQL सर्वर 2014 सामान्य विलंबित स्थायित्व और इन-मेमोरी OLTP स्कीमा-ओनली ड्यूरेबिलिटी की शुरूआत के साथ कुछ हद तक ड्यूरेबल प्रॉपर्टी की सीमाओं को धुंधला करना शुरू कर देता है। मैं उनका उल्लेख केवल पूर्णता के लिए करता हूं, हम इन नई विशेषताओं पर आगे चर्चा नहीं करेंगे। आइए अधिक समस्याग्रस्त ACID गुणों पर चलते हैं:
परमाणु संपत्ति
कई प्रोग्रामिंग भाषाएं परमाणु संचालन provide प्रदान करती हैं जिसका उपयोग दौड़ की स्थितियों और अन्य अवांछनीय समवर्ती प्रभावों से बचाने के लिए किया जा सकता है, जहां निष्पादन के कई सूत्र साझा डेटा संरचनाओं तक पहुंच या संशोधित कर सकते हैं। एप्लिकेशन डेवलपर के लिए, एक परमाणु ऑपरेशन पूर्ण अलगाव की स्पष्ट गारंटी . के साथ आता है बहु-थ्रेडेड प्रोग्राम में अन्य समवर्ती प्रसंस्करण के प्रभावों से।
डेटाबेस की दुनिया में एक समान स्थिति उत्पन्न होती है, जहां कई टी-एसक्यूएल क्वेरी अलग-अलग थ्रेड्स से साझा डेटा (यानी डेटाबेस) को समवर्ती रूप से एक्सेस और संशोधित करते हैं। ध्यान दें कि हम यहां समानांतर प्रश्नों के बारे में बात नहीं कर रहे हैं; साधारण सिंगल-थ्रेडेड क्वेश्चन नियमित रूप से अलग वर्कर थ्रेड्स पर SQL सर्वर के भीतर समवर्ती रूप से चलने के लिए शेड्यूल किए जाते हैं।
दुर्भाग्य से, परमाणु गुण SQL लेनदेन की केवल गारंटी देता है कि लेन-देन के भीतर किए गए डेटा संशोधन एक इकाई के रूप में सफल या विफल . इससे ज्यादा कुछ नहीं। निश्चित रूप से पूर्ण अलगाव . की कोई गारंटी नहीं है अन्य समवर्ती प्रसंस्करण के प्रभाव से। नोटिस यह भी पारित करने में कि परमाणु लेनदेन संपत्ति पढ़ने . के बारे में किसी भी गारंटी के बारे में कुछ नहीं कहती है डेटा।
एकल कथन
एकल कथन . के बारे में भी कुछ खास नहीं है एसक्यूएल सर्वर में। जहां एक स्पष्ट लेनदेन युक्त (BEGIN TRAN...COMMIT TRAN
) मौजूद नहीं है, एक एकल डीएमएल स्टेटमेंट अभी भी एक ऑटोकॉमिट लेनदेन के भीतर निष्पादित होता है। एक ही एसीआईडी गारंटी एक ही बयान पर लागू होती है, और वही सीमाएं भी लागू होती हैं। विशेष रूप से, एक एकल कथन बिना किसी विशेष गारंटी के आता है कि डेटा प्रगति के दौरान नहीं बदलेगा।
निम्नलिखित टॉय एडवेंचरवर्क्स क्वेरी पर विचार करें:
SELECT TH.TransactionID, TH.ProductID, TH.ReferenceOrderID, TH.ReferenceOrderLineID, TH.TransactionDate, TH.TransactionType, TH.Quantity, TH.ActualCost FROM Production.TransactionHistory AS TH WHERE TH.ReferenceOrderID = ( SELECT TOP (1) TH2.ReferenceOrderID FROM Production.TransactionHistory AS TH2 WHERE TH2.TransactionType = N'P' ORDER BY TH2.Quantity DESC, TH2.ReferenceOrderID ASC );
क्वेरी का उद्देश्य उस आदेश के बारे में जानकारी प्रदर्शित करना है जिसे मात्रा के आधार पर प्रथम स्थान दिया गया है। निष्पादन योजना इस प्रकार है:
इस योजना में मुख्य कार्य हैं:
- आवश्यक लेनदेन प्रकार वाली पंक्तियों को खोजने के लिए तालिका को स्कैन करें
- सबक्वायरी में विनिर्देश के अनुसार उच्चतम क्रमित ऑर्डर आईडी खोजें
- गैर-संकुल अनुक्रमणिका का उपयोग करके चयनित ऑर्डर आईडी के साथ पंक्तियां (उसी तालिका में) ढूंढें
- संकलित अनुक्रमणिका का उपयोग करके शेष स्तंभ डेटा देखें
अब कल्पना करें कि एक समवर्ती उपयोगकर्ता ऑर्डर 495 को संशोधित करता है, इसके लेनदेन प्रकार को P से W में बदलता है, और उस परिवर्तन को डेटाबेस में करता है। भाग्य के रूप में, यह संशोधन तब होता है जब हमारी क्वेरी सॉर्ट ऑपरेशन (चरण 2) कर रही होती है।
जब सॉर्ट पूरा हो जाता है, तो चरण 3 में अनुक्रमणिका चयनित ऑर्डर आईडी (जो कि 495 होती है) के साथ पंक्तियों को ढूंढती है और चरण 4 पर कुंजी लुकअप शेष स्तंभों को आधार तालिका से प्राप्त करता है (जहां लेनदेन प्रकार अब डब्ल्यू है) ।
घटनाओं के इस क्रम का अर्थ है कि हमारी क्वेरी स्पष्ट रूप से असंभव परिणाम उत्पन्न करती है:
निर्दिष्ट क्वेरी के रूप में लेनदेन प्रकार पी के साथ ऑर्डर खोजने के बजाय, परिणाम लेनदेन प्रकार डब्ल्यू दिखाते हैं।
मूल कारण स्पष्ट है:हमारी क्वेरी परोक्ष रूप से मान लिया गया था कि जब हमारी सिंगल-स्टेटमेंट क्वेरी प्रगति पर थी तब डेटा नहीं बदल सकता था। इस मामले में अवसर की खिड़की अवरुद्ध प्रकार के कारण अपेक्षाकृत बड़ी थी, लेकिन समान प्रकार की दौड़ की स्थिति क्वेरी निष्पादन के किसी भी चरण में हो सकती है, आम तौर पर बोल रही है। स्वाभाविक रूप से, जोखिम आमतौर पर समवर्ती संशोधनों के बढ़े हुए स्तरों, बड़ी तालिकाओं और जहां अवरुद्ध ऑपरेटर क्वेरी योजना में दिखाई देते हैं, के साथ अधिक होते हैं।
उसी सामान्य क्षेत्र में एक और लगातार मिथक यह है कि MERGE
अलग INSERT
. पर प्राथमिकता दी जानी है , UPDATE
और DELETE
स्टेटमेंट क्योंकि सिंगल-स्टेटमेंट MERGE
परमाणु है। यह बकवास है, बिल्कुल। हम इस तरह के तर्क पर बाद में श्रृंखला में वापस आएंगे।
इस बिंदु पर सामान्य संदेश यह है कि जब तक अन्यथा सुनिश्चित करने के लिए स्पष्ट कदम नहीं उठाए जाते हैं, डेटा पंक्तियाँ और अनुक्रमणिका प्रविष्टियाँ निष्पादन प्रक्रिया के दौरान किसी भी समय बदल सकती हैं, स्थिति बदल सकती हैं, या पूरी तरह से गायब हो सकती हैं। टी-एसक्यूएल प्रश्न लिखते समय डेटाबेस में निरंतर और यादृच्छिक परिवर्तन की एक मानसिक तस्वीर को ध्यान में रखना अच्छा है।
संगति संपत्ति
एसीआईडी संक्षिप्त शब्द के दूसरे शब्द में भी संभावित व्याख्याओं की एक श्रृंखला है। SQL सर्वर डेटाबेस में, संगतता का अर्थ है केवल कि एक लेनदेन डेटाबेस को ऐसी स्थिति में छोड़ देता है जो किसी भी सक्रिय बाधाओं का उल्लंघन नहीं करता है। यह पूरी तरह से सराहना करना महत्वपूर्ण है कि वह कथन कितना सीमित है:डेटा अखंडता और तार्किक स्थिरता की एकमात्र एसीआईडी गारंटी सक्रिय बाधाओं द्वारा प्रदान की जाती है।
SQL सर्वर तार्किक अखंडता को लागू करने के लिए सीमित सीमा प्रदान करता है, जिसमें PRIMARY KEY
. शामिल है , FOREIGN KEY
, CHECK
, UNIQUE
, और NOT NULL
. लेन-देन के समय इन सभी के संतुष्ट होने की गारंटी है। इसके अलावा, SQL सर्वर भौतिक . की गारंटी देता है बेशक, हर समय डेटाबेस की अखंडता।
अंतर्निहित बाधाएं हमेशा हमारे द्वारा पसंद किए जाने वाले सभी व्यवसाय और डेटा-अखंडता नियमों को लागू करने के लिए पर्याप्त नहीं होती हैं। मानक सुविधाओं के साथ रचनात्मक होना निश्चित रूप से संभव है, लेकिन ये जल्दी जटिल हो जाते हैं और इसके परिणामस्वरूप डुप्लिकेट डेटा का संग्रहण हो सकता है।
परिणामस्वरूप, अधिकांश वास्तविक डेटाबेस में अतिरिक्त नियमों को लागू करने के लिए लिखे गए कम से कम कुछ टी-एसक्यूएल रूटीन होते हैं, उदाहरण के लिए संग्रहीत प्रक्रियाओं और ट्रिगर्स में। यह सुनिश्चित करने की जिम्मेदारी पूरी तरह से लेखक की है कि यह कोड सही ढंग से काम करता है - संगति संपत्ति कोई विशिष्ट सुरक्षा प्रदान नहीं करती है।
बिंदु पर जोर देने के लिए, टी-एसक्यूएल में लिखे गए छद्म-बाधाओं को सही ढंग से प्रदर्शन करना होगा, चाहे कोई भी समवर्ती संशोधन हो। एक एप्लिकेशन डेवलपर लॉक स्टेटमेंट के साथ उस तरह के संवेदनशील ऑपरेशन की रक्षा कर सकता है। जोखिम में संग्रहीत कार्यविधि और ट्रिगर कोड के लिए टी-एसक्यूएल प्रोग्रामर के पास उस सुविधा के लिए सबसे निकटतम चीज है, जो तुलनात्मक रूप से बहुत कम इस्तेमाल किया जाने वाला sp_getapplock
है। सिस्टम संग्रहीत प्रक्रिया। इसका मतलब यह नहीं है कि यह एकमात्र या यहां तक कि पसंदीदा विकल्प है, बस यह मौजूद है और कुछ परिस्थितियों में सही विकल्प हो सकता है।
आइसोलेशन प्रॉपर्टी
यह आसानी से ACID लेनदेन गुणों के बारे में सबसे अधिक बार गलत समझा जाता है।
सिद्धांत रूप में, एक पूरी तरह से पृथक लेनदेन अपने जीवनकाल के दौरान डेटाबेस के खिलाफ निष्पादित एकमात्र कार्य के रूप में निष्पादित होता है। अन्य लेन-देन केवल तभी शुरू हो सकते हैं जब वर्तमान लेनदेन पूरी तरह से समाप्त हो गया हो (यानी प्रतिबद्ध या वापस लुढ़का हुआ)। इस तरह से निष्पादित, एक लेन-देन वास्तव में एक परमाणु संचालन होगा , इस सख्त अर्थ में कि एक गैर-डेटाबेस व्यक्ति इस वाक्यांश को लिखेगा।
व्यवहार में, डेटाबेस लेनदेन इसके बजाय अलगाव की डिग्री . के साथ संचालित होते हैं वर्तमान प्रभावी लेनदेन अलगाव स्तर द्वारा निर्दिष्ट (जो समान रूप से स्टैंड-अलोन स्टेटमेंट पर लागू होता है, याद रखें)। यह समझौता (डिग्री अलगाव का) पहले उल्लेखित संगामिति और शुद्धता के बीच व्यापार-नापसंद का व्यावहारिक परिणाम है। एक ऐसी प्रणाली जो सचमुच लेन-देन को एक-एक करके संसाधित करती है, जिसमें समय पर कोई ओवरलैप नहीं होता है, पूर्ण अलगाव प्रदान करेगा लेकिन समग्र सिस्टम थ्रूपुट खराब होगा।
अगली बार
इस श्रृंखला के अगले भाग में समवर्ती मुद्दों, एसीआईडी गुणों और लेनदेन अलगाव की जांच जारी रहेगी, जिसमें क्रमिक अलगाव स्तर पर एक विस्तृत नज़र डाली जाएगी, कुछ का एक और उदाहरण जिसका मतलब यह नहीं हो सकता है कि आप क्या सोचते हैं।
[ पूरी श्रृंखला के लिए सूचकांक देखें ]