2011-12-05 11 views
10

हमें कुछ डेडलॉक के साथ कोई समस्या है और मैंने इसे question पोस्ट किया है।एसक्यूएल सर्वर, एक पंक्ति ताले भरें पूरी तालिका

कुछ मदद और खुद को खोजने के साथ मुझे विश्वास है कि मुझे पता चला कि क्या हो रहा है। लॉक एस्केलेशन को नियंत्रित किए बिना डेडलॉक्स को हल करने के लिए मुझे समझने की आवश्यकता है कि क्यों SQL सर्वर एक पंक्ति डालने पर पूरी तालिका को लॉक करता है।

DECLARE 
    @Type1 INT = 11, 
    @Type2 INT = NULL, 
    @Value1 VARCHAR(20) = '0', 
    @Value2 VARCHAR(20) = '0', 
    @Value3 VARCHAR(20) = '0', 
    @Value4 VARCHAR(20) = '0', 
    @Date1 DATETIME = '2011-11-25', 
    @Date2 DATETIME = '2011-11-25', 
    @Value5 NVARCHAR(50) = '', 
    @Value6 NVARCHAR(50) = '', 
    @Type3 INT = NULL, 
    @Value7 VARCHAR(20) = '4', 
    @Type4 INT = 4, 
    @Type5 INT = 15153, 
    @Type6 INT = 3, 
    @Type7 INT = 31, 
    @Type8 INT = 5976, 
    @Type9 INT = 5044, 
    @Guid1 UNIQUEIDENTIFIER = 'a8293471-3hb4-442b-844f-44t92f17n67s', 
    @Value8 VARCHAR(200) = '02jfgg55savolhffr1mkjf45', 
    @value10 INT = 1, 
    @Option2 BIT = 0, 
    @Value9 VARCHAR(20) = null, 
    @Option1 BIT = 0 

insert into dbo.OurTable 
(
    Type1 
    ,Type2 
    ,Value1 
    ,Value2 
    ,Value3 
    ,Value4 
    ,Date1 
    ,Date2 
    ,Value5 
    ,Value6 
    ,Type3 
    ,Value7 
    ,Type4 
    ,Type5 
    ,Type6 
    ,Type7 
    ,Type8 
    ,Type9 
    ,value10 
    ,Col1 
    ,Col2 
    ,Col3 
    ,Col4 
    ,Value8 
    ,Option2 
    ,Value9 
) 
values 
(
    CASE 
     WHEN [dbo].[GetType](@Type1, null) = 6 AND @Option1 = 1 AND [dbo].[GetType](@Type4, 0) <> 1 
     THEN 7 
     ELSE [dbo].[GetType](@Type1, null) 
    END 
    ,[dbo].[GetType](@Type2, null) 
    ,case when @Value1 = 'null' then null else CAST(@Value1 as numeric(18, 6)) end 
    ,case when @Value2 = 'null' then null else CAST(@Value2 as numeric(18, 6)) end 
    ,case when @Value3 = 'null' then null else CAST(@Value3 as numeric(18, 6)) end 
    ,case when @Value4 = 'null' then null else CAST(@Value4 as numeric(18, 6)) end 
    ,[dbo].[GetDate](@Date1, null) 
    ,[dbo].[GetDate](@Date2, null) 
    ,@Value5 
    ,@Value6 
    ,[dbo].[GetType](@Type3, null) 
    ,case when @Value7 = 'null' then null else CAST(@Value7 as numeric(18, 6)) end 
    ,[dbo].[GetType](@Type4, null) 
    ,@Type6 
    ,case when LOWER(@Type7) = 'null' then null else @Type7 end 
    ,@Type5 
    ,@Type9 
    ,@Type8 
    ,@value10 
    ,GETDATE() 
    ,GETDATE() 
    ,[dbo].[GetGuid](@Guid1) 
    ,[dbo].[GetGuid](@Guid1) 
    ,@Value8 
    ,@Option2 
    ,case when @Value9 = 'null' then null else CAST(@Value9 as int) end 
) 

अगर मैं एक लेनदेन में इस बयान को चलाने और उसके बाद मुझे लगता है कि सत्र से संबंधित 10233 पंक्तियां प्राप्त करने से पहले sys.dm_tran_locks क्वेरी:

यहाँ मेरी डालने बयान (जिसका नाम बदलकर चर के साथ) है।

SELECT * 
FROM sys.dm_tran_locks l 
WHERE l.resource_type <> 'DATABASE' AND l.request_session_id = 65 

65 परीक्षण करते समय मेरी वर्तमान विंडो का सत्र आईडी है।

अगर मैं टेबल लॉकिंग (जो मेरे डेडलॉक का कारण है) को देखता है तो मैं देख सकता हूं कि यह टेबल ऑटटेबल पर एक्स लॉक रखता है।

resource_type resource_associated_entity_id Name resource_lock_partition request_mode request_type request_status 
OBJECT 290100074 OurTable 0 X LOCK GRANT 
OBJECT 290100074 OurTable 1 X LOCK GRANT 
OBJECT 290100074 OurTable 2 X LOCK GRANT 
OBJECT 290100074 OurTable 3 X LOCK GRANT 
OBJECT 290100074 OurTable 4 X LOCK GRANT 
OBJECT 290100074 OurTable 5 X LOCK GRANT 
OBJECT 290100074 OurTable 6 X LOCK GRANT 
OBJECT 290100074 OurTable 7 X LOCK GRANT 
OBJECT 290100074 OurTable 8 X LOCK GRANT 
OBJECT 290100074 OurTable 9 X LOCK GRANT 
OBJECT 290100074 OurTable 10 X LOCK GRANT 
OBJECT 290100074 OurTable 11 X LOCK GRANT 
OBJECT 290100074 OurTable 12 X LOCK GRANT 
OBJECT 290100074 OurTable 13 X LOCK GRANT 
OBJECT 290100074 OurTable 14 X LOCK GRANT 
OBJECT 290100074 OurTable 15 X LOCK GRANT 

मैं अगर यह कारण lock escalation किया जाता है पता नहीं है या अगर यह शुरू से ही मेज पर एक विशेष ताला अनुरोध करता है। किसी भी तरह से यह मुझे deadlocks के साथ परेशानी का कारण बनता है।

कारण वहाँ एक एकल तालिका पर 16 ताला पंक्तियां हों lock partitioning.

मेरा प्रश्न है, कारण है कि यह मेज पर एक आशय अनन्य लॉक (IX) का अनुरोध नहीं करता की वजह से है? इसके बजाय यह एक विशेष लॉक का अनुरोध करता है। मैं इसे कैसे न होने दूँ? मुझे ट्यूनिंग सलाहकार में कोई ट्यूनिंग टिप्स नहीं मिलती है, मैंने पहले ही कोशिश की है।

संपादित करें OurTable पर एक सम्मिलित ट्रिगर है जो OurTable3 पर एक फ़ील्ड अपडेट करता है। यह इस तरह दिखता है:

UPDATE OurTable3 SET Date1 = NULL 
    FROM OurTable3 as E 
     JOIN OurTable2 as C on E.Id = C.FKId 
     JOIN OurTable as ETC on ETC.FKId = C.Id 
      AND (ETC.Date2 IS NULL OR CAST(ETC.Date2 AS DATE) > E.Date1) 
      AND ETC.Type1 = 1 

के रूप में आप यह OurTable अपडेट नहीं होता देखते हैं लेकिन OurTable3 में सही पंक्ति अवगत कराने के लिए OurTable क्वेरी कर सकते हैं।

+1

क्या आपने लेनदेन अलगाव स्तर देखा है? http://msdn.microsoft.com/en-us/library/ms173763।एएसपीएक्स – dash

+1

क्या यह संभव है कि उन सभी कार्यों का संदर्भ 'OurTable' भी है? आप वहां बहुत सारे काम चलाते हैं ... – JNK

+1

टेबल संरचना क्या है ?? क्या आपके पास क्लस्टरिंग कुंजी है? –

उत्तर

10

मुझे जवाब मिला। हमारी टीम में एक डेवलपर से थोड़ा गलती (मैं हमेशा हर किसी को दोष देता हूं :-)। मुझे शायद पहले से ही जवाब पता होना चाहिए क्योंकि मार्टिन स्मिथ ने दूसरे प्रश्न में बताया कि मुझे ALLOW_ROW_LOCKS और ALLOW_PAGE_LOCKS की जांच करनी चाहिए। लेकिन उस समय हमने सोचा कि विभाजन सूचकांक आईडी से संबंधित है और मैंने केवल उस इंडेक्स की जांच की है।

मैंने जो किया वह उसी डेटा के साथ एक नई तालिका बना रहा था। प्रभाव समाप्त हो गया था और मेरे पास केवल नई तालिका पर सही IX लॉक था। तब मैंने हर इंडेक्स बनाया और हर सृजन के बीच परीक्षण किया जब तक कि अचानक मुझे अचानक प्रभाव नहीं पड़ा।

मैं OurTable पर इस सूचकांक पाया:

CREATE NONCLUSTERED INDEX [IX_OurTable] ON [dbo].[OurTable] 
(
    [Col1] ASC, 
    [Col2] ASC, 
    [Col3] ASC, 
    [Col4] ASC, 
    [Col5] ASC 
) 
INCLUDE ([Col6], 
[Col7], 
[Col8], 
[Col9]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF, FILLFACTOR = 90) ON [PRIMARY] 
GO 
ALLOW_ROW_LOCKS = बंद और साथ

ALLOW_PAGE_LOCKS = रवाना यह स्पष्ट है हम डालने और भी चयन पर इस आशय के लिए होगा।

आपकी टिप्पणियों के लिए धन्यवाद और मार्टिन के लिए बहुत धन्यवाद जिन्होंने वास्तव में इन डेडलॉक समस्याओं को हल करने में मेरी मदद की।

+1

आपके समाधान को साझा करने के लिए धन्यवाद, एक मुश्किल जैसा लगता है और मुझे यकीन है कि आपकी पोस्ट दूसरों की मदद करो। – jpierson

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