来自范围的死锁锁定主键索引

时间:2017-09-01 21:08:06

标签: sql-server-2008 deadlock

我在桌子上遇到了奇怪的死锁(几张桌子,但它们都很相似),无论我多少尝试研究Range锁,都无法理解它。一个进程始终只有SELECT并且正在使用RangeS-U,然后尝试将其转换为RangeS-S。为什么Select会首先选择RangeS-U?其他进程执行UPDATE并使用RangeX-X并尝试转换为X.有时第二个进程有X并尝试获取X(或者我正在错误地读取图形)。主键索引字段永远不会更新,并且表上没有其他索引。业务流程的方式,我可以肯定,选择和更新都与具有大重叠的记录一起工作。如果需要,可以提供更多信息,表格模式和死锁图如下所示。

我发布在stackoverflow,但有人建议我也在这里发帖,因为我可能会在这里运气好。

-

CREATE TABLE [dbo].[DeadlockTable] (
    [ID] [bigint] NOT NULL ,
    [Hour] [tinyint] NOT NULL ,
    [Status] [varchar] (32) COLLATE Latin1_General_BIN NOT NULL ,
    [MW] [decimal](19, 6) NULL ,
    [CreationUserID] [int] NULL ,
    [CreationTime] [datetime] NULL ,
    [ModificationUserID] [int] NULL ,
    [ModificationTime] [datetime] NULL ,
    [SubmissionUserID] [int] NULL ,
    [SubmissionTime] [datetime] NULL ,
    [ConfigurationID] [varchar] (64) COLLATE Latin1_General_BIN NULL ,
    CONSTRAINT [PK_DeadlockTable] PRIMARY KEY  CLUSTERED 
    (
        [ID],
        [Hour]
    )  ON [PRIMARY] 
) ON [PRIMARY]
GO

死锁XML -

<deadlock-list>
    <deadlock victim="process5e13b88">
        <process-list>
            <process id="process5e13b88" taskpriority="0" logused="0" waitresource="KEY: 22:72057594344112128 (6123af010c07)" waittime="2978" ownerId="265837907" transactionname="INSERT" lasttranstarted="2017-09-01T10:04:10.767" XDES="0x16fb323b0" lockMode="RangeS-S" schedulerid="2" kpid="5316" status="suspended" spid="83" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-09-01T10:04:10.430" lastbatchcompleted="2017-09-01T10:04:09.907" clientapp="..." hostname="..." hostpid="7980" loginname="..." isolationlevel="serializable (4)" xactid="265837907" currentdb="22" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
                <executionStack>
                    <frame procname="adhoc" line="40" stmtstart="3776" stmtend="7404" sqlhandle="0x020000009555563118dcb9a28a078c9faa795d95341a9119">
                        INSERT INTO #TempTable (
                        ...
                        )
                        SELECT DISTINCT
                        ...
                        FROM Table1 B
                        LEFT JOIN DeadlockTable P ON B.[ID] = {more joins, got cropped}
                    </frame>
                    <frame procname="mssqlsystemresource.sys.sp_executesql" line="1" sqlhandle="0x0400ff7fbe80662601000000000000000000000000000000">
                        sp_executesql
                    </frame>
                    <frame procname="EXEC SPROC" line="386" stmtstart="28814" stmtend="29462" sqlhandle="0x03001600afff210aad8d3f01d0a700000100000000000000">
                        EXEC sp_executesql ...
                    </frame>
                    <frame procname="adhoc" line="1" sqlhandle="0x010016009a0b8926e0fb577e010000000000000000000000">
                        EXEC SPROC ...
                    </frame>
                </executionStack>
                <inputbuf>
                    EXEC SPROC ...
                </inputbuf>
            </process>
            <process id="process5e45b88" taskpriority="0" logused="236" waitresource="KEY: 22:72057594344112128 (55ed2fdeaf5a)" waittime="3130" ownerId="265839001" transactionname="UPDATE" lasttranstarted="2017-09-01T10:04:14.840" XDES="0x484c171b0" lockMode="X" schedulerid="7" kpid="4852" status="suspended" spid="90" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-09-01T10:04:14.817" lastbatchcompleted="2017-09-01T10:04:11.883" clientapp="..." hostname="..." hostpid="7980" loginname="..." isolationlevel="read committed (2)" xactid="265839001" currentdb="22" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
                <executionStack>
                    <frame procname="EXEC SPROC2" line="141" stmtstart="9324" stmtend="10424" sqlhandle="0x03001600a8150d4e1c673f01d0a700000100000000000000">
                        UPDATE BP
                        SET BP.[Status] = CASE @Cancel WHEN 1 THEN &apos;Voided&apos; ELSE &apos;Submitted&apos; END, BP.[MW] = CASE @Cancel WHEN 1 THEN 0 ELSE BP.[MW] END, BP.[SubmissionUserID] = @SubmissionUserID, BP.[SubmissionTime] = @SubmissionTime
                        FROM #FinalResult FR
                        CROSS JOIN Hour25 H25
                        INNER JOIN DeadLockTable  BP ON BP.[ID] = FR.[ID] AND BP.[Hour] = H25.[HE]
                        INNER JOIN fnc_List2Table(@HourList, &apos;,&apos;) HL ON H25.[HE] = HL.[Value] OR @HourList = &apos;0&apos;
                        WHERE (FR.[MarketType] = 1 OR (FR.[MarketType] = 2 AND BP.[Hour] = FR.[Hour]))
                    </frame>
                    <frame procname="adhoc" line="2" stmtstart="18" sqlhandle="0x010016002c9cbb0aa05380f3000000000000000000000000">
                        EXEC SPROC2
                    </frame>
                </executionStack>
                <inputbuf>
                    EXEC SPROC2
                </inputbuf>
            </process>
        </process-list>
        <resource-list>
            <keylock hobtid="72057594344112128" dbid="22" objectname="DealockTable" indexname="PK_DealockTable" id="lock451ea9e80" mode="X" associatedObjectId="72057594344112128">
                <owner-list>
                    <owner id="process5e45b88" mode="X"/>
                </owner-list>
                <waiter-list>
                    <waiter id="process5e13b88" mode="RangeS-S" requestType="wait"/>
                </waiter-list>
            </keylock>
            <keylock hobtid="72057594344112128" dbid="22" objectname="DealockTable" indexname="PK_DealockTable" id="lock109ed6380" mode="RangeS-U" associatedObjectId="72057594344112128">
                <owner-list>
                    <owner id="process5e13b88" mode="RangeS-S"/>
                </owner-list>
                <waiter-list>
                    <waiter id="process5e45b88" mode="X" requestType="convert"/>
                </waiter-list>
            </keylock>
        </resource-list>
    </deadlock>
</deadlock-list>

死锁图 deadlock graph from sql trace

0 个答案:

没有答案