2015-12-22 51 views
0

我在存儲過程中有一個更新查詢,這是導致死鎖的主要原因。更新查詢中的死鎖

此存儲過程用於SSIS包中的foreach循環中。 看起來存儲過程調用Salespreprocessing表並進入死鎖狀態。當我們同時調用這個SSIS包時會發生這種情況。這裏是我的SQL查詢

UPDATE SPP 
SET SPP.Promotion_Id = T.PromotionID  
FROM staging.SalesPreProcessing SPP WITH(INDEX(staging_CIDXSalesPreprocessing1)) 
INNER JOIN #WithConcatenatedPromotionID T 
ON SPP.DocLineNo = T.BillItem 
AND SPP.DocNum = T.BillNumber 
AND SPP.Cust_Code = T.CustomerCode 
AND SPP.ZCS_EAN_CODE = T.ProductCode 
AND SPP.BILLING_REPORTING_DATE = T.PricingDate 
WHERE SPP.InterfaceStatusTrackingID = @in_InterfaceStatusTrackingId AND [email protected]_SetupId 

我已經創建了聚集索引的setupid和表的列的其餘部分的非聚集索引。

這裏是我的非聚集索引

CREATE NONCLUSTERED INDEX [staging_CIDXSalesPreprocessing] on salespreprocessing 
(
    [SetupId] ASC, 
    [InterfaceStatusTrackingID] ASC 
) INCLUDE`enter code here` 
([DocLineNo] , 
    [DocNum] , 
    [Cust_Code] , 
    [ZCS_EAN_CODE] , 
    [Billing_Reporting_Date]   
) 

我仍然得到死鎖

+0

爲什麼不用表中的nolock提示試試? – bmsqldev

+0

@bmsqldev:根據我的理解,我們不能將NOLOCK應用於正在嘗試更新的表。因此,在我的一組行中,我們有一個物理表,我們正在更新,另一個表是臨時表,因此放入如果我錯了,請爲我寫入NOLOCK。 – Namrata

回答

0

首先在非聚集索引似乎毫無意義作爲第一列是setupId你說的是爲羣集列指數。因此,假設setupId值具有足夠的多樣性,查詢將始終使用聚簇索引而非非聚簇索引。主要關鍵是什麼?

在避免死鎖的條款,你需要:

1)確保鎖以相同的順序每次的SP被稱爲foreach循環中花費時間。我不知道你在循環什麼?另一個SP /查詢的結果?如果是這樣,請確保其中有一個ORDER BY

2)foreach在事務中循環嗎?如果它是需要的?每次通過從非事務環境調用SP調用SP後,您能否釋放鎖?

3)在SP內儘可能少的鎖。我看不到用什麼查詢來創建你加入的臨時表,但這可能是問題所在。您需要使用SQL事件探查器來查明哪個對象完全發生了死鎖,但使用諸如ROWLOCK之類的提示可能會有所幫助。

+0

我收到以下錯誤消息:「將nvarchar數據類型轉換爲日期時間數據類型導致超出範圍值。」可能的失敗原因:查詢問題,「ResultSet」屬性設置不正確,參數設置不正確或連接未正確建立。雖然我試圖運行這個特定的存儲過程 – Namrata

+0

要添加上面我的SPP.BILLING_REPORTING_DATE = T.PricingDate實際上是這樣的CONVERT(DATETIME,SPP.BILLING_REPORTING_DATE,103)= T.PricingDate更新查詢 – Namrata

+0

@ Strick01:問題沒有用RowLock解決問題。:( – Namrata