【问题标题】:Deadlock in update query更新查询死锁
【发布时间】:2015-12-22 05:24:56
【问题描述】:

我在存储过程中有一个更新查询,这是导致死锁的主要原因。

此存储过程在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]          
)

我仍然陷入僵局

【问题讨论】:

  • 为什么不在表中使用 nolock 提示并尝试?
  • @bmsqldev:据我了解,我们不能对我们尝试更新的表应用 NOLOCK。所以在我的一组行中,我们有一个正在更新的物理表,另一个是临时表,因此将 NOLOCK 用于临时表是没有意义的。如果我错了,请纠正我

标签: stored-procedures ssis deadlock


【解决方案1】:

首先,非聚集索引似乎毫无意义,因为它的第一列是 setupId,你说它是聚集索引的列。因此,假设 setupId 值足够多样化,查询将始终使用非聚集索引之上的聚集索引。什么是主键?

在避免死锁方面,您需要:

1) 确保每次在 foreach 循环中调用 SP 时都以相同的顺序获取锁。不知道你在循环什么?另一个 SP/查询的结果?如果是这样,请确保其中有一个ORDER BY

2) foreach 循环是否在事务中?如果是,有必要吗?您能否在每次调用 SP 后通过从非事务性环境中调用它来释放锁?

3) 在 SP 中使用尽可能少的锁。我看不到用于创建您加入的临时表的查询,但这可能是问题所在。您需要使用 SQL 事件探查器找出究竟发生死锁的对象,但使用诸如 ROWLOCK 之类的提示可能会有所帮助。

【讨论】:

  • 我收到以下错误:“将 nvarchar 数据类型转换为 datetime 数据类型导致值超出范围。”。可能的失败原因:查询有问题,“ResultSet”属性设置不正确,参数设置不正确,或连接未正确建立。当我尝试运行这个特定的存储过程时
  • 在我的 SPP.BILLING_REPORTING_DATE = T.PricingDate 上面添加实际上是这样的 CONVERT(DATETIME,SPP.BILLING_REPORTING_DATE,103) = T.PricingDate in Update query
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多