2011-01-04 20 views
10

को रोकने वाली पंक्ति को विशेष रूप से लॉक करने के लिए कैसे करें हाय विशेषज्ञ मैं एसक्यूएल सर्वर में एक पंक्ति को कैसे लॉक कर सकता हूं जो सीआरयूडी ऑपरेशन को भी चुनता है। क्या यह संभव है? सीरियलज़ेबल अलगाव स्तर SELECT को रोकता नहीं है। धन्यवादसीआरयूडी ऑपरेशन

उत्तर

11
BEGIN TRAN 

    SELECT 1 
    FROM Table 
    WITH (XLOCK, ROWLOCK) 

COMMIT TRAN 

यह चाल करेगा।

संपादित

दूसरों के द्वारा बताया गया है, जिसे आप लॉक नहीं कर सकते हैं एक पंक्ति को नहीं पढ़ा जा। एक ही रास्ता मैं ऐसा करने का पता इस प्रकार है:

WITH (UPDLOCK, TABLOCK) 

और यह मानते हुए है जो किसी के साथ (NOLOCK) (जो वैसे भी बचा जाना चाहिए) एक SELECT कथन में इस्तेमाल कभी नहीं किया है।

मैंने इसका परीक्षण किया और यह काम करेगा, हालांकि टैबलेट का उपयोग केवल चरम मामलों में किया जाना चाहिए। निश्चित रूप से यदि सहमति की आवश्यकता है, तो यह एक खराब समाधान है और लॉकिंग के किसी अन्य रूप की आवश्यकता होगी। एक तरीका है "थोड़ा सा उपलब्ध/गलत" थोड़ा कॉलम अपडेट करना और केवल पंक्तियां पढ़ें जहां उपलब्ध = सही है। जैसा कि @ जीबीएन ने सुझाव दिया है, READPAST इस के साथ उपयोग किया जा सकता है।

+1

मैंने अभी इसका परीक्षण किया है, और XLOCK चुनने के लिए UPDLOCK के रूप में अच्छा काम करता है। यह भी देखें: http://sqlblog.com/blogs/louis_davidson/archive/2006/12/13/does-xlock-always-prevent-reads-by-others.aspx –

+0

हां, आप सही हैं। हालांकि, मैं सही या गलत मानता हूं कि ओपी एक विशेष लॉक की तलाश में है क्योंकि उन्होंने कहा कि वे "सीआरयूडी को रोकना" चाहते हैं। मुझे नहीं पता कि यह केवल अपडेट के खिलाफ है, या इसमें लॉकिंग पंक्तियां शामिल हैं जो पढ़ी गई हैं। इसलिए मैंने अनन्य लॉक का चयन किया। यदि यह पंक्तियों के खिलाफ नहीं है जो पढ़े गए हैं, तो 100% मैं अपडॉक का उपयोग करूंगा। लिंक के लिए – IamIC

+0

+1 @ केएम धन्यवाद। दिलचस्प! – IamIC

5

इस तरह लेन-देन कुछ अंदर ROWLOCK और UPDLOCK प्रयोग करके देखें:

BEGIN TRANSACTION 

SELECT @ID = ID 
FROM YourTable WITH (ROWLOCK, UPDLOCK) 
WHERE .... 

--more-- 

COMMIT TRANSACTION 

आप एक का चयन करें "गंदे" यह पढ़ने से NOLOCK संकेत का उपयोग करता है नहीं रोका जा सकता लेकिन।

+0

UPDLOCK पढ़ने को रोक नहीं पाएगा। – IamIC

+0

@ IanC, प्रश्न का शीर्षक ** ** सीआरयूडी ऑपरेशन को रोकने के लिए विशेष रूप से एक पंक्ति को कैसे लॉक करें ** –

+0

@KM मुझे पता है। "कैसे * विशेष रूप से ताला * * = एक्सएलक। :-) – IamIC

1

एसक्यूएल सर्वर पहले ही मूल रूप से गंदा पढ़ने से रिकॉर्ड को लॉक करता है क्योंकि इसे अपडेट किया जा रहा है। जब तक अद्यतन/सम्मिलन कॉल पूरा नहीं हो जाता है तब तक चयन कॉल को अवरुद्ध करने का इसका प्रभाव होता है।

+0

यद्यपि कथन सत्य है, एसईटी ट्रांज़ेक्शन इशोलेशन लेवल का उपयोग करके अनौपचारिक (या नोलोक को निर्दिष्ट करना) अभी भी गंदे पढ़ने को वापस कर देगा। –

0

लॉकिंग संकेत (रोलोक) के साथ एक पंक्ति को लॉक करना संभव है, हालांकि एक चयन कथन हमेशा लॉकिंग संकेत (NOLOCK) जोड़कर इसके आसपास हो सकता है जो एक गंदे पढ़ने को प्रदान करेगा।

+0

यह सच नहीं है। एक्सलॉक के साथ, रोलोक एक पंक्ति पर एक पठन लॉक की गारंटी देगा। ब्याज से, NOLOCK को बहिष्कृत किया जा रहा है। – IamIC

+0

दरअसल, यह सच है। मेरा उदाहरण ROWLOCK का उपयोग करता है, न कि XLOCK। हालांकि एक साधारण परीक्षण साबित करेगा कि एक एनओएलओसीके अभी भी एक टेबल के खिलाफ पंक्तियों को एक विशेष लॉक के साथ वापस कर देगा। शुरू ट्रॅन चयन * मेज से (xlock, चप्पू-आंकड़ा) जहां primarykeyid = 1 एक और कनेक्शन का उपयोग करके साथ: चयन के साथ मेज से * (nolock) जहां primarykeyid = 1 दूसरे का चयन बयान अभी भी पंक्तियों रिटर्न भले ही चयनित पंक्ति पर एक विशेष लॉक मौजूद है। –

+0

+1, यह काम करेगा साथ ही साथ @ IanC का उत्तर –

1

साथ ही चप्पू-आंकड़ा, XLOCK के रूप में अन्य लोक ने सुझाव दिया है, मैं इसके अलावा में READPAST पर विचार करेंगे

यह अनुमति देता है छोड़ इस पंक्ति पर ताला करने के लिए अन्य पाठकों और लेखकों की अनुमति देता है। यह समवर्तीता बढ़ा सकता है क्योंकि रॉकॉक द्वारा लॉक सेट, एक्सएलकेके अवरुद्ध अन्यथा

+1

अच्छा बिंदु, हालांकि ओपी को ध्यान रखना चाहिए कि इस स्किप का अर्थ है लॉक की गई पंक्तियों को पूरी तरह से छोड़ना, क्योंकि वे परिणामों में प्रकट नहीं होंगे, जो वांछित हो सकते हैं या नहीं। – IamIC

+0

मुझे रीडपैस्ट के विचार पसंद हैं क्योंकि यह डेवलपर को पंक्ति खोजने की संभावना को संभालने की क्षमता को संभालने की अनुमति नहीं देगा और इसलिए बिना किसी डेडलॉक के जारी रहेगा। – Gwasshoppa

संबंधित मुद्दे