我在存储过程中有一个更新查询,这是造成死锁的主要原因。
此存储过程在foreach
循环中的SSIS包中使用。
看起来存储过程调用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 SPP.setupid=@in_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 :(得分:0)
首先,非聚集索引似乎没有意义,因为它的第一列是setupId,你说它是聚簇索引的列。因此,假设setupId值充分多样化,查询将始终使用聚簇索引超出非聚簇索引。什么是主键?
在避免死锁方面,您需要:
1)每次在foreach循环中调用SP时,确保锁定的顺序相同。我不知道你在循环什么?另一个SP /查询的结果?如果是这样,请确保其中有ORDER BY
。
2)交易中是foreach
循环吗?如果它确实需要?你可以通过从非事务环境中调用SP来释放锁定吗?
3)在SP内尽可能少地锁定。我无法看到用于创建您加入的临时表的查询,但这可能是问题。您需要使用SQL事件探查器来确定正在发生死锁的对象,但使用ROWLOCK
等提示可能会有所帮助。