5

我正在使用我的 SQL Server 2012 试图获得锁。根据我看到的教程,我尝试测试获取表上的排他锁,以便没有其他查询能够从中读取信息,直到事务没有结束,但它只是不工作。即使它在视频中工作,这是我在第一个窗口中的查询:</p>

use TSQL2012

BEGIN transaction

update tele with (TABLOCKX, holdlock) 
set cor = '12'

waitfor delay '00:05'
go

然后在第二个查询窗口中我只是尝试:

select * from tele

它工作得很好,尽管理论上应该有“排他”锁来防止这种情况。为什么会这样?我也试过

set transaction isolation level serializable on

而且没有延迟,但选择总是成功的。有任何想法吗?

4

1 回答 1

3

我已经在两个不同的表上尝试过,并且可以轻松地重现您发现的内容。这是正在发生的事情:

如果 Sql-Server 在更新表之前将行返回到 SELECT 查询,那么很可能在那一刻,您的远程表上已经存在与排他锁不兼容的锁。例如,如果某个地方的另一个会话已经在表上拥有了读取器锁,那么您的 UPDATE 语句将被挂起,WAIT_TYPE 为 LCK_M_X,这意味着您的 UPDATE 被阻塞,等待与排他锁不兼容的锁释放。由于所有锁都与独占表锁不兼容,因此当任何其他会话使用任何类型的锁访问表时,您的更新语句将被挂起。

在 SQL Management Studio 的第三个实例中,右键单击您的服务器并打开活动监视器。过滤您的数据库并登录并重新运行实验。如果表是应用程序经常使用的表,并且 SELECT 在 UPDATE 之前运行,那么您会注意到 UPDATE 上的 LCK_M_X WAIT_TYPE。

尝试创建一个只有您知道的新表并重新运行实验。它应该工作。

于 2018-01-26T17:41:15.020 回答