有没有办法确定给定查询可能应用于 SQL 对象的锁?

Sae*_*ati 3 sql-server locking

考虑一个简单的查询,就像一条select语句一样简单:

select * from Teachers where Name like N'%John%'
Run Code Online (Sandbox Code Playgroud)

一旦我开始这个查询,它就完成了。因此,我没有机会看到sp_who2这个查询对数据库对象应用了什么类型的锁。

我可以用事务语句来扩充这个查询:

begin transaction

select * from Teachers where Name like N'%John%'

-- Here, I won't commit transaction, thus holding the lock
Run Code Online (Sandbox Code Playgroud)

但坦率地说,这似乎不是自然锁定检测的正确方法,因为我已经使用事务语句操纵了默认行为。

我们是否有一个工具,比如Display Estimated Execution Plan向我们展示有关锁定给定查询的一些信息?如果不是,我们如何找出给定查询可以在数据库上应用哪种类型的锁,因为它们执行得太快而无法检测到。

Mar*_*ith 7

不,没有运行它就无法知道。

打开一个事务的问题是你仍然看不到所有的锁。在读提交时,只要读取行而不是事务结束,就会释放共享锁。即使对于一直保持到事务结束的锁,如果锁升级,您也会错过在此之前取出的更高粒度的锁。

如果这是一台开发机器,您可以使用跟踪标志 1200(未记录)

DBCC TRACEON(1200,3604,-1);
SELECT ....
DBCC TRACEOFF(1200,3604,-1);
Run Code Online (Sandbox Code Playgroud)

这会将锁定事件输出到消息选项卡,通常最好执行批处理两次,因为第一次运行将包含许多与编译和执行相关的内容。

还可以使用 SQL Server Profiler/Trace 和扩展事件来查看获取和释放的锁。

同样,这最好在开发服务器上完成,因为这些可能是非常频繁的事件,即使进行过滤也可能会在繁忙的服务器上增加大量开销。