sql-server-2012 – 检测SQL Server中的锁定表或行

我正在尝试了解/了解如何跟踪被阻止会话的详细信息.

所以我创建了以下设置:

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 | Status       | BlkBy | dbname   | Command          | SPID | REQUESTID
-----+--------------+-------+----------+------------------+------+----------
52   | sleeping     |   .   | foodb    | AWAITING COMMAND | 52   | 0        
53   | sleeping     |   .   | foodb    | AWAITING COMMAND | 53   | 0        
54   | SUSPENDED    | 52    | foodb    | UPDATE           | 54   | 0        
56   | RUNNABLE     |   .   | foodb    | SELECT INTO      | 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 | keylock hobtid=72057594046054400 dbid=6 id=lock4ed1dd780 mode=X associatedobjectId=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实际上不包含我正在寻找的信息.

所以我要找的是一个返回类似的查询
“session 54正在等待表foo中的锁定”.

一些背景信息:

我试图解决的现实生活中的问题有点复杂,但归结为“会话54在哪个表等待的问题”.有问题的问题涉及一个较大的存储过程,它更新了几个表,并从一个访问某些表的视图中选择.即使我们启用了快照隔离和读取提交快照,也会阻止select语句.弄明白选择被阻止的原因(我认为如果启用了快照隔离,我认为这是不可能的)将是下一步.

作为第一步,我想了解那个会话正在等待什么.

解决方法

我认为这可以满足您的需求.
USE 'yourDB'
GO
SELECT  
    OBJECT_NAME(p.[object_id]) Blockedobject
FROM    sys.dm_exec_connections AS blocking
    INNER JOIN sys.dm_exec_requests blocked
        ON blocking.session_id = blocked.blocking_session_id
    INNER JOIN sys.dm_os_waiting_tasks waitstats
        ON waitstats.session_id = blocked.session_id
    INNER JOIN sys.partitions p ON SUBSTRING(resource_description,PATINDEX('%associatedobjectId%',resource_description) + 19,LEN(resource_description)) = p.partition_id

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 'EastRiver' 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...