कमरों और टैग के बीच एकरूपता प्राप्त करने और यह सुनिश्चित करने का एकमात्र पोर्टेबल तरीका है कि कमरे हटाए जाने के बाद कभी वापस न हों, उन्हें SELECT FOR UPDATE के साथ लॉक करना है ।
हालांकि कुछ प्रणालियों में लॉकिंग समवर्ती नियंत्रण का एक साइड इफेक्ट है, और आप FOR UPDATE निर्दिष्ट किए बिना समान परिणाम प्राप्त करते हैं। स्पष्ट रूप से।
इस समस्या को हल करने के लिए, थ्रेड 1 को SELECT id FROM rooms FOR UPDATE , जिससे थ्रेड 2 को rooms . से हटाने से रोका जा सके जब तक थ्रेड 1 नहीं हो जाता। क्या यह सही है?
यह आपके डेटाबेस सिस्टम द्वारा उपयोग किए जा रहे समवर्ती नियंत्रण पर निर्भर करता है।
-
MyISAMMySQL. में (और कई अन्य पुराने सिस्टम) क्वेरी की अवधि के लिए पूरी तालिका को लॉक कर देते हैं। -
SQL Serverमें ,SELECTक्वेरीज़ उनके द्वारा जांचे गए रिकॉर्ड्स/पृष्ठों/टेबल्स पर साझा लॉक लगाती हैं, जबकिDMLक्वेरीज़ में अपडेट लॉक होते हैं (जो बाद में एक्सक्लूसिव हो जाते हैं या शेयर्ड लॉक में डिमोट हो जाते हैं)। अनन्य ताले साझा ताले के साथ असंगत हैं, इसलिए या तोSELECTयाDELETEक्वेरी तब तक लॉक रहेगी जब तक कि दूसरा सत्र शुरू नहीं हो जाता। -
डेटाबेस में जो
MVCC. का उपयोग करते हैं (जैसेOracle,PostgreSQL,MySQLInnoDB. के साथ ), एकDMLquery रिकॉर्ड की एक प्रति बनाता है (एक या दूसरे तरीके से) और आम तौर पर पाठक लेखकों को ब्लॉक नहीं करते हैं और इसके विपरीत। इन डेटाबेस के लिए, एकSELECT FOR UPDATEकाम आएगा:यह या तो लॉक हो जाएगाSELECTयाDELETEजब तक कोई अन्य सत्र नहीं हो जाता, तब तक क्वेरी करें, जैसेSQL Serverकरता है।
किसी को REPEATABLE_READ का उपयोग कब करना चाहिए लेन-देन अलगाव बनाम READ_COMMITTED SELECT ... FOR UPDATE . के साथ ?
आम तौर पर, REPEATABLE READ प्रेत पंक्तियों को मना नहीं करता है (पंक्तियाँ जो संशोधित होने के बजाय किसी अन्य लेन-देन में दिखाई देती हैं या गायब हो जाती हैं)
-
Oracle. में और पहले केPostgreSQLसंस्करण,REPEATABLE READवास्तव मेंSERIALIZABLE. का समानार्थी है . मूल रूप से, इसका मतलब है कि लेन-देन शुरू होने के बाद किए गए परिवर्तनों को नहीं देखता है। तो इस सेटअप में, आखिरीThread 1क्वेरी कमरे को वापस कर देगी जैसे कि इसे कभी हटाया नहीं गया है (जो आप चाहते थे या नहीं भी हो सकता है)। यदि आप कक्षों को हटाए जाने के बाद नहीं दिखाना चाहते हैं, तो आपकोSELECT FOR UPDATEके साथ पंक्तियों को लॉक कर देना चाहिए -
InnoDB. में ,REPEATABLE READऔरSERIALIZABLEअलग-अलग चीजें हैं:SERIALIZABLE. में पाठक मोड ने उनके द्वारा मूल्यांकन किए गए रिकॉर्ड पर अगली-कुंजी लॉक सेट किया है, जो समवर्तीDML. को प्रभावी ढंग से रोकता है उन पर। इसलिए आपकोSELECT FOR UPDATE. की आवश्यकता नहीं है क्रमबद्ध मोड में, लेकिनREPEATABLE READमें उनकी आवश्यकता है याREAD COMMITED।
ध्यान दें कि आइसोलेशन मोड पर मानक यह निर्धारित करता है कि आप अपने प्रश्नों में कुछ विशिष्टताओं को नहीं देखते हैं, लेकिन यह परिभाषित नहीं करते हैं कि कैसे (लॉकिंग के साथ या MVCC के साथ) या अन्यथा)।
जब मैं कहता हूं "आपको SELECT FOR UPDATE " मुझे वास्तव में "कुछ डेटाबेस इंजन कार्यान्वयन के दुष्प्रभावों के कारण" जोड़ना चाहिए था।