SQL Server 2008死锁图执行堆栈的完整性如何?
当我在 SQL Server 中获取死锁图 xml 时,它向我显示每个进程的执行堆栈,例如(我已删除大部分属性):
<process>
<executionStack>
<frame>INSERT INTO MYTABLE</frame>
<frame>INSERT INTO MYTABLE</frame>
</executionStack>
<inputbuf>INSERT INTO MYTABLE</inputbuf>
</process>
我知道帧列表不包含事务中的所有帧,但它确实如此吗?包含与死锁有关的所有帧,因此我不需要再进一步查看?或者我是否还需要检查同一事务中前面的 sql 语句以全面了解死锁的原因?
编辑:为了进一步澄清,如果在两个单独的 spid 中运行,以下代码可能会导致自身死锁:
select * from mytable where column = @arg delete from mytable where column = @arg
死锁图会显示 select 语句以及删除语句,还是仅显示删除语句,因为它是事务中的最后一个语句?如果没有看到 select 语句,就很难确定正确的修复(例如,select 上的 updlock 提示)。
When I get the deadlock graph xml in SQL Server, it shows me an executionStack for each process, e.g. (I have removed most of the attributes):
<process>
<executionStack>
<frame>INSERT INTO MYTABLE</frame>
<frame>INSERT INTO MYTABLE</frame>
</executionStack>
<inputbuf>INSERT INTO MYTABLE</inputbuf>
</process>
I know the list of frames does not contain all the frames in the transaction, but does it contain all the frames that are implicated in the deadlock, so I do not need to look any further? Or do I need to also examine the preceding sql statements in the same transaction to get a complete picture as to the cause of the deadlock?
Edit: to clarify further, the following can deadlock itself if run in two separate spids:
select * from mytable where column = @arg
delete from mytable where column = @arg
Will the deadlock graph show the select statement as well as the delete statement, or only the delete statement because that was the last statement in the transaction? Without seeing the select statement too, it is difficult to identify the correct fix (e.g., updlock hint on the select).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要在同一事务中检查前面的sql语句。
死锁图仅显示发生死锁时执行的语句的调用堆栈。实际获取死锁资源的语句可能不存在。这很容易证明如下。
连接 1
连接 2(在 Conn 1 之后快速执行)
死锁图
未显示对首先获取锁的列
foo
的分配。(注意:如果没有 GO 语句来使语句分开批次,在这种情况下,您会看到有问题的语句,但一般来说,锁获取可能发生在调用堆栈的更下方,因此实际获取锁的语句仍然不会显示)
You need to examine the preceding sql statements in the same transaction.
The deadlock graph just shows you the call stack for the statements executing when the deadlock occurred. The statements that actually acquired the deadlocked resources may not be present. This is easily demonstrated as follows.
Connection 1
Connection 2 (Execute quickly after Conn 1)
Deadlock Graph
The assignments to column
foo
that acquired the locks in the first place aren't shown.(NB: Without the
GO
statement to make the statements separate batches you would in this case see the offending statement but in general the lock acquisition might occur further down the call stack so the statement that actually acquired the locks still wouldn't be shown)