TABLOCKX无效

5

我正在使用SQL Server 2012,尝试掌握锁的使用。根据我看到的教程,我尝试测试在表上获取独占锁,以便没有其他查询能够读取它的信息,直到事务结束,但是它并没有起作用。即使在视频中它是有效的,这里是我的查询:

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

同时,没有延迟,但选择操作总是成功。有什么想法吗?


1
无法重现这个问题 - 在我的情况下,在执行UPDATE之后,在提交/回滚该事务之前,对该表进行的SELECT操作会被阻塞(正如预期的那样)。 - marc_s
你是否已经开启了快照隔离 - Vladimir Baranov
@VladimirBaranov无所谓,他正在使用SERIALIZABLE。 - usr
暂时无法重现,因为尚不清楚再现该行为的条件。 - usr
1个回答

3
我已经在两个不同的表上尝试过,并且可以轻松地重现您发现的问题。 以下是发生的情况:
如果Sql-Server在表更新之前向SELECT查询返回行,则很可能此时在tele表上已经存在与独占锁不兼容的锁。例如,如果某处已经对表具有读取器锁定的其他会话,则您的UPDATE语句将被挂起,并显示WAIT_TYPE为LCK_M_X,这意味着您的UPDATE被阻止,等待不兼容的独占锁定释放。由于所有锁都与独占表锁不兼容,因此当任何其他会话使用任何类型的锁访问表时,您的更新语句都将被暂停。
在第3个SQL Management Studio实例中,右键单击服务器并打开活动监视器。筛选您的数据库和登录信息,重新运行实验。如果该表是应用程序频繁使用的内容并且SELECT在UPDATE之前运行,则您将注意到UPDATE上的LCK_M_X WAIT_TYPE。
请尝试创建只有您知道的新表,并重新运行实验。它应该可以工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接