我正在尝试了解/学习如何跟踪被阻止会话的详细信息。
因此,我创建了以下设置:
create table foo (id integer not null primary key, some_data varchar(20));
insert into foo values (1, 'foo');
commit;
现在,我从两个不同的客户端两次连接到数据库。
第一届会议:
begin transaction
update foo set some_data = 'update'
where id = 1;
我明确地不承诺在那里保留锁。
在第二届会议上,我发表了同样的声明,当然还有人由于锁定而等待。现在,我尝试使用不同的查询浮动,以查看会话2正在等待foo
表。
sp_who2
显示以下内容(我删除了一些列以仅显示重要信息):
SPID | 现状 BlkBy | DBName | 指令| SPID | 要求 ----- + -------------- + ------- + ---------- + ---------- -------- + ------ + ---------- 52 | 睡觉 。| foodb | 等待命令| 52 | 0 53 | 睡觉 。| foodb | 等待命令| 53 | 0 54 | 已暂停| 52 | foodb | 更新| 54 | 0 56 | 可运行 。| foodb | 选择进入| 56 | 0
这是预料之中的,会话54被来自会话52的未提交更改阻止。
查询sys.dm_os_waiting_tasks
也显示了这一点。该声明:
select session_id, wait_type, resource_address, resource_description
from sys.dm_os_waiting_tasks
where blocking_session_id is not null;
返回:
session_id | wait_type | resource_address | resource_description ----------- + ----------- + -------------------- + ----- -------------------------------------------------- -------------------------- 54 | LCK_M_X | 0x000000002a35cd40 | 键锁hobtid = 72057594046054400 dbid = 6 id = lock4ed1dd780模式= X relatedObjectId = 72057594046054400
同样,这是预期的。
我的问题是,我不知道如何找到会话54正在等待的实际对象名称。
我发现,要加入一些查询sys.dm_tran_locks
和sys.dm_os_waiting_tasks
这样的:
SELECT ....
FROM sys.dm_tran_locks AS l
JOIN sys.dm_os_waiting_tasks AS wt ON wt.resource_address = l.lock_owner_address
但是在我上面的测试场景中,此联接不返回任何内容。因此,要么该连接是错误的,要么dm_tran_locks
实际上不包含我在寻找的信息。
因此,我要寻找的是一个返回如下内容的查询:
“ 会话54正在等待表中的锁foo
”。
一些背景信息:
我要解决的现实问题更加复杂,但归结为“会话54在哪个表上等待”的问题。所涉及的问题涉及一个用于更新几个表的大型存储过程,以及一个从访问其中一些表的视图中进行选择的选择。select
即使我们已隔离快照并启用了读取已提交快照,该语句也会被阻止。下一步是确定为什么选择被阻止(如果启用了快照隔离,我认为这是不可能的)。
第一步,我想了解该会话正在等待什么。
msdn.microsoft.com/zh-cn/library/ms190345.aspx说您的联接是正确的。
—
Max Vernon
@MaxVernon:感谢您确认。但是后来我更加困惑了。尽管我知道存在锁定和阻塞的会话,为什么它不返回任何内容?
—
a_horse_with_no_name 2014年
我无法重新创建您在SQL Server 2012中看到的问题。我创建了一个测试数据库,启用了RCSI,创建了表,并运行了两个update语句,并且看到上一个查询返回的行。
—
Max Vernon
如果您想要视觉帮助来检测锁,则可以使用一种称为SQL锁查找器的开源工具。您可以在以下网址找到源代码:github.com/LucBos/SqlLockFinder或在以下网址下载可执行文件:sqllockfinder.com我们也喜欢您可以对代码做出的任何贡献,以便我们对其进行改进。
—
Luc Bos