2010-09-22 14 views
8

मैं एक रिकॉर्ड लॉक करना चाहता हूं और फिर कोई भी उस रिकॉर्ड में बदलाव नहीं कर सकता है। जब मैं ताला छोड़ देता हूं, तो लोग रिकॉर्ड बदल सकते हैं।पंक्ति लॉक कैसे करें?

इस बीच एक रिकॉर्ड लॉक हो गया है, मैं उपयोगकर्ता को एक चेतावनी दिखाना चाहता हूं कि रिकॉर्ड लॉक हो गया है और परिवर्तनों की अनुमति नहीं है।

मैं यह कैसे कर सकता हूं?

मैंने सभी अलगाव स्तरों का प्रयास किया है, लेकिन उनमें से कोई भी व्यवहार नहीं चाहता है। कुछ अलगाव स्तर लॉक जारी होने तक प्रतीक्षा करें और फिर एक बदलाव करें। मुझे यह नहीं चाहिए, क्योंकि इस समय अद्यतन को लॉक होने की अनुमति नहीं है।

रिकॉर्ड लॉक करने और सभी परिवर्तनों से इनकार करने के लिए मैं क्या कर सकता हूं?

मैं एसक्यूएल सर्वर का उपयोग 2008

+0

यह डेटाबेस पर निर्भर करता है। कौनसा? – pascal

+0

एसक्यूएल सर्वर 2008 – Martijn

उत्तर

0

इतने पर इस duplicate question देखें।

मूल रूप से यह बताया गया है:

begin tran 

select * from [table] with(holdlock,rowlock) where id = @id 

--Here goes your stuff 

commit tran 

आर्काइव

कुछ इस तरह हो सकता है?

update t 
set t.IsLocked = 1 
from [table] t 
where t.id = @id 

कहीं अद्यतन ट्रिगर में:

if exists (
select top 1 1 
from deleted d 
join inserted i on i.id = d.id 
where d.IsLocked = 1 and i.RowVersion <> d.RowVersion) 
begin 
print 'Row is locked' 
rollback tran 
end 
+0

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

1

Sql सर्वर संकेत ताला लगा है, लेकिन इन एक प्रश्न के दायरे तक सीमित हैं।

यदि रिकॉर्ड लॉक करने का निर्णय किसी एप्लिकेशन में लिया जाता है, तो आप उसी तंत्र को आशावादी लॉकिंग के रूप में उपयोग कर सकते हैं और एप्लिकेशन से रिकॉर्ड में किसी भी बदलाव को अस्वीकार कर सकते हैं।

रिकॉर्ड पर लॉक के रूप में टाइमस्टैम्प या गाइड का उपयोग करें और गलत लॉकिंग कुंजी दिए जाने पर रिकॉर्ड में प्रवेश या परिवर्तन से इनकार करें। रिकॉर्ड्स को फिर से अनलॉक करने के लिए सावधान रहें या आपको अनाथ

+1

मैंने इस तरह के दृष्टिकोण के बारे में सोचा है, लेकिन अगर आवेदन दुर्घटनाग्रस्त हो तो क्या होगा? या अगर सर्वर नीचे चला जाता है। मैं ऐसी स्थिति में रिकॉर्ड कैसे अनलॉक करूं? – Martijn

+0

मुझे लगता है कि कोई आसान तरीका नहीं है। लॉक को एक डेटाटाइम रिकॉर्ड करके समाप्त कर दें, जिसे लॉक किया गया था और बहुत लंबे समय तक मौजूद ताले को साफ करने के लिए ट्रिगर या अनुसूचित नौकरी का उपयोग करें। आप जो अनिवार्य रूप से कर रहे हैं वह निराशावादी लॉकिंग है। यह भी देखें: http://stackoverflow.com/questions/386162/pessimistic-lock-in-t-sql – stombeur

9

धारणा के साथ कि यह एमएस एसक्यूएल सर्वर है, तो शायद आप UPDLOCK चाहते हैं, संभवतः ROWLOCK (Table hints) के साथ संयुक्त हो। मैं मुसीबत एक सभ्य लेख जो सिद्धांत का वर्णन करता है खोजने आ रही हैं, लेकिन यहाँ त्वरित उदाहरण है:

SELECT id From mytable WITH (ROWLOCK, UPDLOCK) WHERE id = 1 

यह बयान लेन-देन की अवधि के लिए पंक्ति पर एक update lock स्थापित करेंगे (इसलिए यह जानकारी रखना महत्वपूर्ण है जब लेनदेन खत्म हो जाएगा)। चूंकि अपडेट लॉक incompatible with exclusive locks (रिकॉर्ड अपडेट करने के लिए आवश्यक हैं) के रूप में, यह लेनदेन समाप्त होने तक किसी को भी इस रिकॉर्ड को अपडेट करने से रोक देगा।

ध्यान दें कि इस रिकॉर्ड को संशोधित करने की कोशिश करने वाली अन्य प्रक्रियाओं को तब तक अवरुद्ध कर दिया जाएगा जब तक लेनदेन पूरा नहीं हो जाता है, फिर भी लेनदेन समाप्त होने के बाद वे जो भी लिखने के लिए अनुरोध करते हैं, तब तक जारी रहेगा (जब तक उन्हें समय-समय पर समाप्त नहीं किया जाता है या मृतक प्रक्रिया के रूप में बंद नहीं किया जाता है)। यदि आप इसे रोकना चाहते हैं तो आपकी अन्य प्रक्रियाओं को अतिरिक्त संकेतों का उपयोग करने की आवश्यकता है ताकि अगर कोई असंगत ताला पता लगाया जा सके या रिकॉर्ड को छोड़ दिया जाए तो रिकॉर्ड को छोड़ दें।


इसके अलावा, आप जबकि उपयोगकर्ता इनपुट के लिए इंतज़ार कर रिकॉर्ड लॉक करने के लिए इस विधि का उपयोग नहीं करना चाहिए। यदि यह आपका इरादा है तो आपको अपनी तालिका में कुछ प्रकार के "संशोधित" कॉलम को जोड़ना चाहिए।

तंत्र ताला लगा एसक्यूएल सर्वर वास्तव में केवल/डेटा अखंडता की रक्षा करने के लिए गतिरोध को रोकने के उपयोग के लिए उपयुक्त हैं - लेन-देन आम तौर पर संभव जितना संक्षिप्त रखा जाना चाहिए और जब तक उपयोगकर्ता इनपुट के लिए इंतज़ार कर निश्चित रूप से नहीं रखा जाना चाहिए।

+0

जब मैं इसका उपयोग करता हूं तो अद्यतन कथन लॉक होने तक प्रतीक्षा करता है और फिर अद्यतन करता है। मुझे यह व्यवहार नहीं चाहिए। जैसे ही एक रिकॉर्ड अवरुद्ध हो जाता है, उपयोगकर्ता को एक संदेश देखना होगा। इसे इस तरह से करने से, मैं उपयोगकर्ता को सूचित नहीं कर सकता क्योंकि अपडेट स्टेटमेंट लॉक जारी होने तक प्रतीक्षा करता है। मैं अद्यतन कथन को रोकना चाहता हूं और किसी भी तरह से एक त्रुटि/अपवाद/चेतावनी देना चाहता हूं ताकि मैं उपयोगकर्ता को सूचित कर सकूं। – Martijn

+0

@ मार्टिजन - आपका दूसरा अपडेट स्टेटमेंट 'नोवाइट' संकेत के साथ निष्पादित करने की आवश्यकता है, जो टाइमआउट के इंतजार के बजाए लॉक का सामना करने के तुरंत बाद इसे वापस कर देगा। – Justin

+0

क्या कथन को आईडीटेबल से (आईडी, 1) कहां से मेरे आईडीटेबल से चयन आईडी नहीं पढ़नी चाहिए? – nash

0

आप लॉक को रिलीज़ होने की प्रतीक्षा नहीं करना चाहते हैं और जैसे ही आप लॉक का सामना करते हैं, संदेश दिखाएं, अगर ऐसा है तो आपने NOWAIT को आजमाया है। अधिक जानकारी के लिए Table Hints (Transact-SQL) और SQL Server 2008 Table Hints देखें। NOWAIT का लाभ प्राप्त करने के लिए आपको अधिक जानकारी के लिए Google पर संपादन लॉक करने की आवश्यकता है।

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