लॉक करने के दो सामान्य तरीके हैं।
सबसे पहले, आपके पास निराशावादी लॉकिंग है। इस दृष्टिकोण में, आप पंक्ति को लॉक करते हैं (SELECT ... FOR UPDATE
) जो किसी और को पंक्ति बदलने से रोकता है। फिर आप UPDATE
करें . जब आप अपना परिवर्तन करते हैं, तो लॉक जारी हो जाता है। इस मामले में संस्करण संख्या/टाइमस्टैम्प कॉलम (कम से कम लॉकिंग का समर्थन नहीं करने के लिए) होने की कोई आवश्यकता नहीं है और कोड अपेक्षाकृत आसान है।
निराशावादी लॉकिंग का नकारात्मक पक्ष यह है कि जब भी कोई उपयोगकर्ता संभावित रूप से डेटा संपादित करने वाले पृष्ठ पर बैठा रहता है, तो आपको लॉक को होल्ड करने की आवश्यकता होती है। यदि आप वेब-आधारित एप्लिकेशन बना रहे हैं तो यह तकनीकी रूप से वास्तव में कठिन है क्योंकि HTTP एक स्टेटलेस प्रोटोकॉल है। अनुरोध जो प्रारंभ में पृष्ठ को प्रस्तुत करता है उसे सामान्य रूप से कनेक्शन पूल से कनेक्शन प्राप्त होगा, SELECT
. करें , और फिर पृष्ठ के पूर्ण हो जाने के बाद कनेक्शन को पूल से वापस कर दें। डेटा को अपडेट करने का बाद का अनुरोध आम तौर पर एक अलग डेटाबेस सत्र के साथ एक अलग कनेक्शन पर होता है ताकि आप पहले सत्र में पंक्ति को लॉक न कर सकें और इसे दूसरे में अपडेट कर सकें। यदि आप पंक्ति को निराशावादी रूप से लॉक करना चाहते हैं, तो आपको यह सुनिश्चित करने के लिए बैक एंड पर बहुत सारे काम करने की आवश्यकता होगी कि एक डेटाबेस कनेक्शन एक विशेष मध्य स्तरीय सत्र से जुड़ा हुआ था जब तक कि उपयोगकर्ता डेटा संपादित नहीं कर लेता। यह आम तौर पर मापनीयता पर बहुत नकारात्मक प्रभाव डालता है और सभी प्रकार की सत्र प्रबंधन समस्याओं का परिचय देता है-- आप कैसे जानते हैं, उदाहरण के लिए, क्या मैंने एक पृष्ठ का अनुरोध किया है, एक पंक्ति को लॉक किया है, और फिर कभी भी लॉग आउट या बदलाव किए बिना अपना ब्राउज़र बंद कर दिया है? आप कब तक डेटाबेस में लॉक किए गए रिकॉर्ड को छोड़ने जा रहे हैं? क्या होता है यदि कोई अन्य सत्र पंक्ति को लॉक करने का प्रयास कर रहा है? यदि आप पहले व्यक्ति लंच के लिए बाहर गए तो आप उस सत्र को कब तक लॉक होने की प्रतीक्षा करने देंगे? आम तौर पर, लोग वेब-आधारित ऐप्स में निराशावादी लॉकिंग लागू नहीं करते हैं क्योंकि सत्र और सत्र स्थिति को प्रबंधित करना बहुत ही अव्यावहारिक है।
दूसरा विकल्प आशावादी लॉकिंग है। इस दृष्टिकोण में, आप पंक्ति में एक संस्करण संख्या/टाइमस्टैम्प जोड़ते हैं। जब आप डेटा को क्वेरी करते हैं तो आप इस संस्करण संख्या/टाइमस्टैम्प का चयन करते हैं। फिर आप इसे अपने WHERE
. में इस्तेमाल करें क्लॉज जब आप बाद में अपडेट करते हैं और जांचते हैं कि वास्तव में कितनी पंक्तियों को संशोधित किया गया था। यदि आप ठीक एक पंक्ति को संशोधित करते हैं, तो आप जानते हैं कि जब से आपने इसे पढ़ा है तब से पंक्ति नहीं बदली है। यदि आप 0 पंक्तियों को संशोधित करते हैं, तो आप जानते हैं कि पंक्ति बदल गई है और आप त्रुटि को संभाल सकते हैं।
इसलिए, उदाहरण के लिए, आप संस्करण संख्या के साथ डेटा का चयन करेंगे
SELECT address_line1, city, state, zip, version
FROM addressTable
WHERE address_id = `<<some key>>`
जब आप अपडेट करने के लिए तैयार थे, तो आप कुछ ऐसा करेंगे जहां आप version
. का उपयोग करते हैं आपके UPDATE
. में और अगर पंक्ति बदल गई तो एक त्रुटि फेंक दें
UPDATE addressTable
SET address_line1 = `<<new address line 1>>`,
city = `<<new city>>`,
state = `<<new state>>`,
zip = `<<new zip>>`,
version = version + 1
WHERE address_id = `<<some key>>`
AND version = `<<version you read initially>>`
IF( SQL%ROWCOUNT = 0 )
THEN
-- Darn. The row must have changed since you read it. Do something to
-- alert the user. Most likely, the application will need to re-query the
-- data to see what the address has been changed to and then ask the user
-- whether they want to re-apply the changes.
RAISE_APPLICATION_ERROR( -20001, 'Oops, the row has changed since you read it.' );
END IF;
आपका आवेदन तब त्रुटि के साथ कुछ उपयोगी करेगा। आम तौर पर, इसका मतलब कुछ ऐसा करना होगा जैसे डेटा को फिर से क्वेरी करना, उपयोगकर्ता को परिवर्तन प्रस्तुत करना, और उनसे पूछना कि क्या वे अभी भी अपने परिवर्तनों को लागू करना चाहते हैं। यदि, उदाहरण के लिए, मैं एक पता पढ़ता हूं और इसे संपादित करना शुरू करता हूं, दोपहर के भोजन पर जाता हूं, मेरे सहयोगी लॉग इन करते हैं, उसी पते को पढ़ते हैं, कुछ संपादन करते हैं और इसे सहेजते हैं, तो मैं वापस लौटता हूं और अपने परिवर्तनों को सहेजने का प्रयास करता हूं, यह आम तौर पर समझ में आता है मुझे यह बताने के लिए कि मेरे सहयोगी ने पहले ही पता बदल कर कुछ नया कर दिया है-- क्या मैं संपादन करना जारी रखना चाहता हूं या क्या मैं उन्हें छोड़ना चाहता हूं।