में रिकॉर्ड्स हटाने से अधिक हो गया है, मैं एक ऐसी प्रक्रिया का परीक्षण कर रहा हूं जो कई बार कई रिकॉर्ड हटा देता है। यह TRUNCATE TABLE
नहीं हो सकता है, क्योंकि वहां ऐसे रिकॉर्ड हैं जिन्हें रहने की आवश्यकता है।एसक्यूएल सर्वर लॉक टाइमआउट लूप
-- Do not block if records are locked.
SET LOCK_TIMEOUT 0
-- This process should be chosen as a deadlock victim in the case of a deadlock.
SET DEADLOCK_PRIORITY LOW
SET NOCOUNT ON
DECLARE @Count
SET @Count = 1
WHILE @Count > 0
BEGIN TRY
BEGIN TRANSACTION -- added per comment below
DELETE TOP (1000) FROM MyTable WITH (ROWLOCK, READPAST) WHERE MyField = SomeValue
SET @Count == @@ROWCOUNT
COMMIT
END TRY
BEGIN CATCH
exec sp_lock -- added to display the open locks after the timeout
exec sp_who2 -- shows the active processes
IF @@TRANCOUNT > 0
ROLLBACK
RETURN -- ignoring this error for brevity
END CATCH
MyTable एक क्लस्टर टेबल है:
अधिक संख्या के कारण, मैं एक पाश इस के समान में हटाना हड्डी टूट गई है। MyField क्लस्टर सूचकांक में पहले कॉलम में है। यह रिकॉर्ड के तार्किक समूह को इंगित करता है, इसलिए MyField = SomeValue
अक्सर कई रिकॉर्ड चुनते हैं। मुझे कोई परवाह नहीं है कि वे किस क्रम में हटाए जाते हैं जब तक एक समूह को एक समय में संसाधित किया जाता है। इस टेबल पर कोई अन्य अनुक्रमणिका नहीं है।
मैंने उत्पादन में देखा गया लॉक एस्केलेशन से बचने के लिए ROWLOCK
संकेत जोड़ा। मैंने अन्य प्रक्रियाओं द्वारा लॉक किए गए रिकॉर्ड्स को हटाने से बचने के लिए READPAST
संकेत जोड़ा। ऐसा कभी नहीं होना चाहिए, लेकिन मैं सुरक्षित होने की कोशिश कर रहा हूं।
समस्या: कभी-कभी यह लूप लॉक टाइमआउट 1222 "लॉक अनुरोध समय अवधि समाप्त हो जाती है" जब यह एकमात्र चीज चलती है।
मैं सकारात्मक हूं कि इस प्रक्रिया का परीक्षण करने के दौरान इस प्रणाली पर कोई अन्य गतिविधि नहीं है, क्योंकि यह मेरा स्वयं का डेवलपर बॉक्स है, कोई और कनेक्ट नहीं है, इसमें कोई अन्य प्रक्रिया नहीं चल रही है, और प्रोफाइलर कोई नहीं दिखाता है गतिविधि।
मैं एक ही बाद में एक ही स्क्रिप्ट को फिर से चला सकता हूं और यह कहां से निकलता है, खुशी से रिकॉर्ड्स को हटा देता है - अगले लॉक टाइमआउट तक।
मैंने 1222 त्रुटि को अनदेखा करने और हटाने का पुनः प्रयास करने के लिए BEGIN TRY
/BEGIN CATCH
को आजमाया है और हटाएं पुनः प्रयास करें, लेकिन यह उसी लॉक टाइमआउट त्रुटि के साथ तुरंत विफल हो जाता है। अगर मैं पुनः प्रयास करने से पहले एक छोटी देरी जोड़ता हूं तो यह फिर भी विफल हो जाता है।
मुझे लगता है कि लॉक टाइमआउट पृष्ठ विभाजन की तरह कुछ की वजह से हैं, लेकिन मुझे यकीन नहीं है कि यह वर्तमान पाश पुनरावृत्ति के साथ क्यों संघर्ष करेगा। पूर्व डिलीट स्टेटमेंट पहले ही पूरा हो चुका था, और मैंने सोचा कि इसका मतलब है कि कोई पेज स्प्लिट भी समाप्त हो गया था।
डेली लूप अपने खिलाफ लॉक टाइमआउट क्यों मार रहा है?
क्या इस तरह की प्रक्रिया इस लॉक टाइमआउट से बच सकती है या पता लगाना कि यह फिर से शुरू करना सुरक्षित है?
यह 2005
SQL सर्वर पर है - संपादित करें -
मैं ताला कहा: प्रोफाइलर को समय समाप्त घटना। इसे हटाने के दौरान एक PAGELOCK पर बाहर समय है:
Event Class: Lock:Timeout
TextData: 1:15634 (one example of several)
Mode: 7 - IU
Type: 6 - PAGE
बी सी सी पृष्ठ की रिपोर्ट इन पृष्ठों मास्टर डेटाबेस (आईडी 1) की सीमा के बाहर हैं।
- संपादित करें 2 -
मैं एक BEGIN TRY
/BEGIN CATCH
जोड़ा गया है और कैच ब्लॉक में एक exec sp_lock
भाग गया।यहां मैंने देखा है:
spid dbid ObjId IndId Type Resource Mode Status
19 2 1401108082 1 PAG 1:52841 X GRANT (tempdb.dbo.MyTable)
19 2 1401108082 0 TAB IX GRANT (tempdb.dbo.MyTable)
Me 2 1401108082 0 TAB IX GRANT (tempdb.dbo.MyTable)
Me 1 1115151018 0 TAB IS GRANT (master..spt_values) (?)
एसपीआईडी 1 एक एसक्यूएल सर्वर टास्क प्रबंधक है। इन कार्य प्रबंधकों में से एक MyTable पर ताले हासिल क्यों करेगा?
आप एसक्यूएल ट्रेस में विभिन्न ताला घटनाओं का पता लगाने अगर आप फैलाना कर सकते हैं क्या हो रहा है देखने के लिए कोशिश की है? –
बस किया, इसका उल्लेख करने के लिए धन्यवाद। मैंने ऊपर लॉक टाइमआउट जानकारी जोड़ा। निश्चित नहीं है कि वास्तव में क्या लॉक किया जा रहा है। –
एक और संपादन: लॉक टाइमआउट के तुरंत बाद कुछ sp_lock जानकारी जोड़ा गया। –