Uma*_*air 7 sql-server deadlock azure-sql-database
我有以下死锁xml
<deadlock>
<victim-list>
<victimProcess id="process3340d548c8" />
</victim-list>
<process-list>
<process id="process3340d548c8" taskpriority="0" logused="1676" waitresource="KEY: 5:72057594083016704 (80e6876e1037)" waittime="4843" ownerId="6974726" transactionname="user_transaction" lasttranstarted="2018-05-25T13:52:16.627" XDES="0x330b1b4458" lockMode="U" schedulerid="1" kpid="34260" status="suspended" spid="201" sbid="2" ecid="0" priority="0" trancount="2" lastbatchstarted="2018-05-25T13:52:16.657" lastbatchcompleted="2018-05-25T13:52:16.657" lastattention="1900-01-01T00:00:00.657" clientapp=".Net SqlClient Data Provider" hostname="RD0003FF430FC8" hostpid="12344" loginname="officearchitect" isolationlevel="read committed (2)" xactid="6974726" currentdb="5" currentdbname="OfficeArchitect_Performance_Test" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValueHyperlink_DeleteByAttributeValueIds" queryhash="0xdc817ac17586cee6" queryplanhash="0x8759f1b16359d45e" line="7" stmtstart="340" stmtend="644" sqlhandle="0x03000500f793ca333699da00eba8000001000000000000000000000000000000000000000000000000000000">
DELETE
AVH
FROM
[model].[AttributeValueHyperlink] AVH
INNER JOIN
@AttributeValueIdsTable AVT
ON
[AVT].EntityId = [AVH].AttributeValueI </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValue_DeleteByAttributeValueIds" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="10" stmtstart="490" stmtend="660" sqlhandle="0x030005006cae724fc899da00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[AttributeValueHyperlink_DeleteByAttributeValueIds]
@AttributeValueId </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValue_DeleteByModelItemIds" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="13" stmtstart="732" stmtend="918" sqlhandle="0x03000500def65a51d299da00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC model.AttributeValue_DeleteByAttributeValueIds
@AttributeValueIds = @AttributeValueId </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.ModelItem_Generic_Delete" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="41" stmtstart="2062" stmtend="2208" sqlhandle="0x0300050096f1cb432e9cda00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[AttributeValue_DeleteByModelItemIds]
@ModelItemIdTabl </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.ModelItem_Object_Delete" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="25" stmtstart="1088" stmtend="1302" sqlhandle="0x0300050061e52c65069dda00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[ModelItem_Generic_Delete]
@ObjectIdTable,
@MarkAsDeleted,
@DeletedBy,
@DeletedO </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 5 Object Id = 1697441121] </inputbuf>
</process>
<process id="process3330f29088" taskpriority="0" logused="1744" waitresource="KEY: 5:72057594083016704 (5b32eda0fe69)" waittime="4575" ownerId="6948390" transactionname="user_transaction" lasttranstarted="2018-05-25T13:52:14.370" XDES="0x331cb2c458" lockMode="U" schedulerid="2" kpid="29596" status="suspended" spid="181" sbid="2" ecid="0" priority="0" trancount="2" lastbatchstarted="2018-05-25T13:52:14.403" lastbatchcompleted="2018-05-25T13:52:14.390" lastattention="1900-01-01T00:00:00.390" clientapp=".Net SqlClient Data Provider" hostname="RD0003FF430FC8" hostpid="12344" loginname="officearchitect" isolationlevel="read committed (2)" xactid="6948390" currentdb="5" currentdbname="OfficeArchitect_Performance_Test" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValueHyperlink_DeleteByAttributeValueIds" queryhash="0xdc817ac17586cee6" queryplanhash="0x8759f1b16359d45e" line="7" stmtstart="340" stmtend="644" sqlhandle="0x03000500f793ca333699da00eba8000001000000000000000000000000000000000000000000000000000000">
DELETE
AVH
FROM
[model].[AttributeValueHyperlink] AVH
INNER JOIN
@AttributeValueIdsTable AVT
ON
[AVT].EntityId = [AVH].AttributeValueI </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValue_DeleteByAttributeValueIds" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="10" stmtstart="490" stmtend="660" sqlhandle="0x030005006cae724fc899da00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[AttributeValueHyperlink_DeleteByAttributeValueIds]
@AttributeValueId </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValue_DeleteByModelItemIds" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="13" stmtstart="732" stmtend="918" sqlhandle="0x03000500def65a51d299da00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC model.AttributeValue_DeleteByAttributeValueIds
@AttributeValueIds = @AttributeValueId </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.ModelItem_Generic_Delete" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="41" stmtstart="2062" stmtend="2208" sqlhandle="0x0300050096f1cb432e9cda00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[AttributeValue_DeleteByModelItemIds]
@ModelItemIdTabl </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.ModelItem_Relationship_Delete" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="23" stmtstart="1078" stmtend="1302" sqlhandle="0x030005000d989e704f9dda00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[ModelItem_Generic_Delete]
@RelationshipIdTable,
@MarkAsDeleted,
@DeletedBy,
@DeletedO </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 5 Object Id = 1889441805] </inputbuf>
</process>
<process id="process330f11fc28" taskpriority="0" logused="32948" waitresource="KEY: 5:72057594083016704 (80e6876e1037)" waittime="2558" ownerId="6941127" transactionname="user_transaction" lasttranstarted="2018-05-25T13:52:13.970" XDES="0x33199a4458" lockMode="U" schedulerid="2" kpid="91236" status="suspended" spid="193" sbid="2" ecid="0" priority="0" trancount="2" lastbatchstarted="2018-05-25T13:52:21.987" lastbatchcompleted="2018-05-25T13:52:21.983" lastattention="1900-01-01T00:00:00.983" clientapp=".Net SqlClient Data Provider" hostname="RD0003FF430FC8" hostpid="12344" loginname="officearchitect" isolationlevel="read committed (2)" xactid="6941127" currentdb="5" currentdbname="OfficeArchitect_Performance_Test" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValueHyperlink_DeleteByAttributeValueIds" queryhash="0xdc817ac17586cee6" queryplanhash="0x8759f1b16359d45e" line="7" stmtstart="340" stmtend="644" sqlhandle="0x03000500f793ca333699da00eba8000001000000000000000000000000000000000000000000000000000000">
DELETE
AVH
FROM
[model].[AttributeValueHyperlink] AVH
INNER JOIN
@AttributeValueIdsTable AVT
ON
[AVT].EntityId = [AVH].AttributeValueI </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValue_DeleteByAttributeValueIds" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="10" stmtstart="490" stmtend="660" sqlhandle="0x030005006cae724fc899da00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[AttributeValueHyperlink_DeleteByAttributeValueIds]
@AttributeValueId </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValue_DeleteByModelItemIds" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="13" stmtstart="732" stmtend="918" sqlhandle="0x03000500def65a51d299da00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC model.AttributeValue_DeleteByAttributeValueIds
@AttributeValueIds = @AttributeValueId </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.ModelItem_Generic_Delete" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="41" stmtstart="2062" stmtend="2208" sqlhandle="0x0300050096f1cb432e9cda00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[AttributeValue_DeleteByModelItemIds]
@ModelItemIdTabl </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.ModelItem_Relationship_Delete" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="23" stmtstart="1078" stmtend="1302" sqlhandle="0x030005000d989e704f9dda00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[ModelItem_Generic_Delete]
@RelationshipIdTable,
@MarkAsDeleted,
@DeletedBy,
@DeletedO </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.RelationshipPair_DeleteByModelItemIds" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="21" stmtstart="1252" stmtend="1462" sqlhandle="0x03000500bc1cd015159eda00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[ModelItem_Relationship_Delete]
@RelationshipIds,
0,
@DeletedBy,
@DeletedOn, </frame>
<frame procname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.ModelItem_Object_Delete" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="20" stmtstart="878" stmtend="1076" sqlhandle="0x0300050061e52c65069dda00eba8000001000000000000000000000000000000000000000000000000000000">
EXEC [model].[RelationshipPair_DeleteByModelItemIds]
@ObjectIdTable,
@DeletedBy,
@DeletedO </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 5 Object Id = 1697441121] </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594083016704" dbid="5" objectname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValueHyperlink" indexname="IX_AttributeValueHyperlink_AttributeValueId" id="lock3320f42880" mode="U" associatedObjectId="72057594083016704">
<owner-list>
<owner id="process3330f29088" mode="U" />
</owner-list>
<waiter-list>
<waiter id="process3340d548c8" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594083016704" dbid="5" objectname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValueHyperlink" indexname="IX_AttributeValueHyperlink_AttributeValueId" id="lock3320f4fb00" mode="X" associatedObjectId="72057594083016704">
<owner-list>
<owner id="process330f11fc28" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process3330f29088" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594083016704" dbid="5" objectname="7b7e4b64-e8dd-4a72-8f98-447678798791.model.AttributeValueHyperlink" indexname="IX_AttributeValueHyperlink_AttributeValueId" id="lock3320f42880" mode="U" associatedObjectId="72057594083016704">
<owner-list>
<owner id="process3340d548c8" mode="U" requestType="wait" />
</owner-list>
<waiter-list>
<waiter id="process330f11fc28" mode="U" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
Run Code Online (Sandbox Code Playgroud)
据我所知,我们在IX_AttributeValueHyperlink_AttributeValueId
索引上有 3 个行级锁。我不确定为什么其中一些 ( process330f11fc28
) 对该索引有 X 锁,但其他人没有。
此删除的执行计划也如下所示
我不明白为什么会发生僵局。一切似乎都很好。
顺便说一下,这是在 sql azure 数据库上,因此它使用 RCSI 隔离级别,但是我们的事务(在该C#
层中)设置为使用已提交读。
Pau*_*ite 10
我不明白为什么会发生僵局。
对于这个执行计划,删除每一行所涉及的加锁操作的顺序是:
U
锁定非聚集索引(在索引查找时获取)U
锁定聚集索引(在删除操作符处获取)X
锁定聚集索引(在删除操作符处)X
锁定非聚集索引(在删除操作符处)我不知道为什么...... process330f11fc28 在这个索引上有一个 X 锁,但其他人没有。
该计划没有阻塞运算符,因此它是一个简单的管道(粗略地说,在处理下一行之前,每一行都到达了管道的末尾)。
发生死锁时,一个进程(会话 193)X
锁定了非聚集索引行(上面的最后一步)。会话 181 和 201 在第一步被阻塞,试图U
在会话 193 排他性锁定的同一个非聚集索引行上获得不兼容的锁。
详细的解释有点牵连,我提前表示歉意。
在对非聚集索引更新锁由发动机自动注意避免的常见类型转换死锁,其发生在两个进程获取S
在同一资源上的锁,则两个尝试转换到X
。每个都被另一个阻止转换S
为X
,因此会发生死锁。
使用U
锁可以防止这种情况,因为U
它与S
另一个U
. 自然S
地,在 RCSI 下通常不会使用U
锁,但这些锁是。这避免了尝试更新行的陈旧版本。
U
在 RCSI 下,自动锁定仅针对为更新操作提供行定位器的表实例。查询中的其他表(包括对更新目标的任何其他引用)继续使用行版本控制。
这些自动U
锁与常规更新锁具有不同的生命周期(例如可能带有UPDLOCK
提示)。常规U
锁一直保持到事务结束。内部U
锁一直保持到语句的末尾,但有一个例外:如果获取锁的同一个计划运算符可以推断出该行不符合更新条件,则会立即释放锁。
请参阅我在 Read Committed Snapshot Isolation 下的文章数据修改。
此自动U
锁不提供防止循环死锁的保护。在事务中修改资源 A 和资源 B 的两个事务,但顺序相反,保证死锁:
上面的“修改”包括插入、更新、删除等。
问题中的示例是此主题的变体,其中:
X
该行U
在 R2 行上获取U
R2 上的锁U
在 R1上获取(会话 201 也在U
R2 行等待获取,但它是一个无辜的旁观者。)
需要明确的是:对于问题中显示的精确执行计划,不会发生上述确切的死锁序列。由于缺少阻塞运算符和/或非聚集锁的获取点和释放点之间的分离,会话 181 无法U
在 R2 上保持并继续在U
R1上请求U
。U
索引查找找到的任何锁定行都保证X
在处理下一个查找行之前转换为。
尽管如此,仅仅因为这是现在声明的计划,并不意味着这就是发生僵局时的计划。例如,当发生语句级重新编译时,SQL Server 可以看到表变量的基数。这很可能会导致散列连接计划。
在散列连接计划中,表变量中的行将用于构建散列表。完成后,SQL Server 可以开始从 读取行AttributeValueHyperlink
,U
锁定索引扫描发出的每一行(现在没有什么可搜索的)。
在散列连接中,每个探测端的行都根据连接谓词进行评估。如果找到匹配的行继续到聚集索引中删除运算符,其中集群U
,X
以及非聚集X
锁被视为查找和删除与当前行中的条目的一部分。
但是,如果行未在散列连接处连接,U
则不会释放锁。U
未连接行的锁将继续累积,直到当前语句结束时它们都被释放。这只是U
在一个操作员(非聚集索引扫描)上获取锁但在另一个操作员(散列连接)上进行资格测试的结果。
无论如何,多个U
锁使报告的死锁成为可能。
当然,简单的嵌套循环计划在处理相同的数据时也可能会死锁(锁只是更明显的循环死锁)。为了避免死锁,您需要确保输入集是不相交的,或者每个集中的行都以严格相同的顺序处理(以相同的方式排序,并由执行计划以相同的顺序处理)。
归档时间: |
|
查看次数: |
2745 次 |
最近记录: |