这是一个DynamicsAX应用程序,我现在经常看到以下死锁。如果我正确理解输出,INSERT进入表CUSTTRANS将被INSERT阻塞到表CUSTSETTLEMENT中。我检查了两个表,都没有触发器,所以我不清楚如何导致另一个死锁? CUSTTRANS表确实启用了更改跟踪,但没有启用CUSTSETEMENT。
<event name="xml_deadlock_report" package="sqlserver" timestamp="2016-07-19T23:43:24.567Z">
<data name="xml_report">
<value>
<deadlock>
<victim-list>
<victimProcess id="processb7c273c38" />
</victim-list>
<process-list>
<process id="processb7c273c38" taskpriority="0" logused="9000" waitresource="KEY: 5:72057881131876352 (9006753b740b)" waittime="37640" ownerId="221473485" transactionname="user_transaction" lasttranstarted="2016-07-19T16:42:46.317" XDES="0xb7caa3078" lockMode="RangeS-S" schedulerid="6" kpid="1940" status="suspended" spid="122" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2016-07-19T16:42:46.760" lastbatchcompleted="2016-07-19T16:42:46.737" lastattention="2016-07-19T13:12:49.450" clientapp="Microsoft Dynamics AX" hostname="DW22" hostpid="3076" loginname="xxx" isolationlevel="read committed (2)" xactid="221473485" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="2872" sqlhandle="0x020000005b952a20985c14b98773bd4fb5fd593a90918fd00000000000000000000000000000000000000000">
INSERT INTO CUSTTRANS (ACCOUNTNUM,TRANSDATE,VOUCHER,...,REPORTINGEXCHADJUSTMENTRE </frame>
<frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>(@P1 nvarchar(21),@P2 datetime2...@P67 numeric(32,4)</inputbuf>
</process>
<process id="process1d15b0cf8" taskpriority="0" logused="3009456" waitresource="KEY: 5:72057881131876352 (e7873f5a29fe)" waittime="3566" ownerId="221391316" transactionname="user_transaction" lasttranstarted="2016-07-19T16:38:55.940" XDES="0x21b5e31d8" lockMode="RangeI-N" schedulerid="3" kpid="6320" status="suspended" spid="62" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2016-07-19T16:43:20.997" lastbatchcompleted="2016-07-19T16:43:20.993" lastattention="2016-07-19T15:31:56.060" clientapp="Microsoft Dynamics AX" hostname="DW22" hostpid="3076" loginname="xxxxx" isolationlevel="read committed (2)" xactid="221391316" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="1262" sqlhandle="0x020000000af3f41be10a624051e59a5f47e43bd38431bc5f0000000000000000000000000000000000000000">
INSERT INTO CUSTSETTLEMENT (TRANSRECID,TRANSDATE,OFFSETTRANSVOUCHER,...,RECID) VALUES (@P1,@P2,@P3...,@P40) </frame>
</executionStack>
<inputbuf>
(@P1 bigint,@P2 datetime2,@P3 nvarchar(21)...,@P40 bigint)INSERT INTO CUSTSETTLEMENT (TRANSRECID,TRANSDATE,OFFSETTRANSVOUCHER,...</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057881131876352" dbid="5" objectname="MicrosoftDynamicsAX.dbo.CUSTSETTLEMENT" indexname="I_075TRANSINDEX" id="lock6d97d4380" mode="RangeX-X" associatedObjectId="72057881131876352">
<owner-list>
<owner id="process1d15b0cf8" mode="RangeX-X" />
</owner-list>
<waiter-list>
<waiter id="processb7c273c38" mode="RangeS-S" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057881131876352" dbid="5" objectname="MicrosoftDynamicsAX.dbo.CUSTSETTLEMENT" indexname="I_075TRANSINDEX" id="lock7102fa100" mode="RangeS-S" associatedObjectId="72057881131876352">
<owner-list>
<owner id="processb7c273c38" mode="RangeS-S" />
</owner-list>
<waiter-list>
<waiter id="process1d15b0cf8" mode="RangeI-N" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</value>
</data>
<action name="collect_system_time" package="package0">
<value>2016-07-19T23:43:24.567Z</value>
</action>
<action name="client_hostname" package="sqlserver">
<value />
</action>
<action name="context_info" package="sqlserver">
<value />
</action>
<action name="attach_activity_id_xfer" package="package0">
<value>CE2E9A01-A31C-464F-9288-AC45C7927760-574</value>
</action>
<action name="attach_activity_id" package="package0">
<value>634B86DC-58AB-4870-9170-5575B9C12D0A-1</value>
</action>
</event>
答案 0 :(得分:0)
首先想到的是(不看图) - 它们之间有一个FK。而且我认为它确实在那里。
CUSTTRANS
可能是子表,CUSTSETTLEMENT
是父表。插入CUSTTRANS
时 - 服务器检查父表CUSTSETTLEMENT
中是否有适当的密钥(从CUSTTRANS
行引用)。并对该列上的父表/索引中的键放置共享锁。
第二个事务是在父表CUSTSETTLEMENT
中插入值并更新I_075TRANSINDEX
索引。我假设您在一个事务中在该表中插入了许多值,因此在某些时刻您已经使用独占锁锁定了一些范围并尝试锁定更多。但是 - 在另一个范围 - 已经从第一个插入到CUSTTRANS
的共享锁定,它检查父表中是否存在相应的行以确保FK完整性。
是的,FK有一些非常常见的与它们相关的死锁场景。另一个是:将多个(足以启用升级)插入子表并从父表中删除许多 - 两者都将尝试锁定整个相关表并将失败。
解决方案(一如既往):