在两个相等的INSERT查询之间锁定同一个键

时间:2015-06-17 16:48:24

标签: sql sql-server

我们有一个INSERT查询:

INSERT INTO dbo.AnotherTable    
(CorrespondenceRecordKey,
FeedbackFileDataKey,
FeedbackRecordStatusCode,
RecordLevelErrorCode,   
ActivityPeriodKey,
SwiftNessHandlerId,                 
LastProcessStatusCode,  
LastProcessStatusDate,  
RecordGUID, 
IsLastAnswer,   
GeneralFileDataXMLKey,  
RowReference)

OUTPUT

INSERTED.RecordKey,
INSERTED.CorrespondenceRecordKey,
INSERTED.FeedbackFileDataKey,
INSERTED.FeedbackRecordStatusCode,
INSERTED.RecordLevelErrorCode,
INSERTED.ActivityPeriodKey,
INSERTED.CorrespondenceCRMID,
INSERTED.CorrespondenceSyncKey,
INSERTED.SwiftNessHandlerId,
INSERTED.LastProcessStatusCode,
INSERTED.LastProcessStatusDate,
INSERTED.RecordGUID,
INSERTED.IsLastAnswer,
INSERTED.GeneralFileDataXMLKey,
INSERTED.RowReference 

INTO #Temp3

SELECT

NRFC.RecordKey AS CorrespondenceRecordKey,
SomeTable.RecordKey AS FeedbackFileDataKey,
fid.FeedbackRecordStatusCode,
fid.RecordLevelErrorCode,
fid.ActivityPeriodKey,
fid.SwiftNessHandlerId,
fid.LastProcessStatusCode,
fid.LastProcessStatusDate,
fid.RecordGUID,
fid.IsLastAnswer,
fid.GeneralFileDataXMLKey,
fid.RowReference

FROM #Temp1 fid
INNER JOIN #Temp2 NRFC 
    ON NRFC.RecordGUID = fid.CorrespondenceRecordGUID
INNER JOIN dbo.SomeTable 
    ON SomeTable.RecordGUID = fid.FeedbackFileDataGUID;

INSERT是努力工作程序的一部分。该过程适用于并行线程。

我们CLUSTERED INDEX上的SomeTable(RecordKey)NONCLUSTERED上的SomeTable.RecordGUID。执行计划显示NONCLUSTERED INDEX的使用情况。

至少我们在DEAD LOCKNONCLUSTERED INDEX发生了两个相等INSERTS之间的NONCLUSTERED INDEX。插件在S\d{1,2}([-+]?E\d{1,2})+上询问S型锁和X型锁,问题是:

  1. 为什么会发生X型锁定?
  2. 为什么发生死锁?
  3. 我怎么打呢?

1 个答案:

答案 0 :(得分:0)

每次SQL Server插入/更新行时都会发生Xtype锁定。如果进程A对资源1具有锁定并且正在等待资源2(在事务的上下文中),而进程B在等待资源1时锁定资源2,则发生死锁(与简单锁定非常不同)。

SQL Server将检测到这一点并终止任何进程执行最少量的进程并让另一个进程完成事务。对抗它的最简单方法是以相同的顺序访问资源 - 这种过程获取资源1的方式将阻止其他进程启动,第一个资源将完成,释放所有内容,然后第二个进程可以执行它拥有的内容去做。