我有一个来自我的应用程序的SQL语句。我想知道这个语句获得了哪些锁定;如何在SQL服务器中实现? 这个语句已经涉及到死锁,我正在尝试分析;我无法重现死锁。 我正在运行MS SQL Server 2005。
我有一个来自我的应用程序的SQL语句。我想知道这个语句获得了哪些锁定;如何在SQL服务器中实现? 这个语句已经涉及到死锁,我正在尝试分析;我无法重现死锁。 我正在运行MS SQL Server 2005。
您可以在事务中运行该语句,但不提交该事务。由于锁将保持到事务提交,因此这给您检查锁的时间。(默认情况下,不是无限期,而是5分钟。)
例如:
BEGIN TRANSACTION
select * from table
然后打开管理工具并检查锁定情况。它们在“管理” -> “活动监视器” -> “按对象锁定”或“按进程锁定”中。完成后,请运行:
COMMIT TRANSACTION
DBCC TRACEON(1222,-1)
这里有一个查询,可以显示所有活动锁定、谁拥有它们以及它们所在的对象。我很久以前从Technet文章中找到了它。它适用于SQL 2000和2005(对于2005,请将sysobjects更改为sys.objects)。如果您想将其限制为仅针对此数据库和独占锁,请取消WHERE子句的注释。
select 'Locks' as Locks,
spid, nt_username, name, hostname, loginame, waittime, open_tran,
convert(varchar ,getdate() - last_batch, 114) as TimeSinceLastCommand,
case req_mode
when 0 then 'Not granted'
when 1 then 'Schema stability'
when 2 then 'Schema modification'
when 3 then 'Intent shared'
when 4 then 'Shared intent update'
when 5 then 'Intent shared shared'
when 6 then 'Intent exclusive'
when 7 then 'Shared Intent Exclusive'
when 8 then 'Shared'
when 9 then 'Update'
when 10 then 'Intent insert NULL'
when 11 then 'Intent shared exclusive'
when 12 then 'Intent update'
when 13 then 'Intent shared-update'
when 14 then 'Exclusive'
when 15 then 'Bulk operation'
else str(req_mode) end as LockMode
from master..syslockinfo
left join sysobjects so on so.id = rsc_objid
left join master..sysprocesses sp on sp.spid = req_spid
--where rsc_dbid = (select db_id()) and ltrim(req_mode) in (6,7,11,14)
您可以在开发环境中运行分析器跟踪查询,以查看确切的锁定情况。这通常是大量数据,但其中许多都是您可以快速浏览的模式。例如,在读提交隔离级别下,当您执行表或索引扫描时,您将看到一系列被获取和释放的锁定(每个行在读取之前必须被锁定,并且在读取后立即释放)。
您使用哪种隔离级别?哪些查询导致死锁?您是否使用涵盖多个更新的显式事务,还是单个语句死锁?
死锁最典型的情况是一个序列为(更新表x,更新表y)的事务,以及一个序列为(更新表y,更新表x)的第二个事务。常见的解决方案是确保在查询中使用相同的更新序列。
请告诉我们它们是什么类型的查询,因为不同类型的事务存在不同的常见问题。