在 SQL Server 2012 中,我明确锁定了一个表,如下所示:
引用:How to explicitly lock a table in Microsoft SQL Server (looking for a hack - uncooperative client)
当发生此锁定时,我正在该表上运行一个带有 NOLOCK 的 SELECT 查询。但是在我停止窗口 1 并等待更多时间之前,查询不会返回数据。
为什么 NOLOCK
没有按预期工作?
--窗口1
DECLARE @TranName VARCHAR(300)
SET @TranName = 'MyTran';
BEGIN TRANSACTION @TranName
DECLARE @Current INT
SET @Current = 0
DECLARE @LoopCount INT
SET @LoopCount = 1;
WHILE @Current < 1
BEGIN
SET @LoopCount = @LoopCount+1;
PRINT @LoopCount
ALTER TABLE DBATCPH ADD LockTest INT
ALTER TABLE DBATCPH DROP COLUMN LockTest
WAITFOR DELAY '00:01';
END
GO
Go
--窗口2
SELECT TOP 1 * FROM DBATCPH NOLOCK
最佳答案
如果您在事务中发出 ALTER TABLE
命令,SQL Server 将获得一个 SCH-M
(模式修改)锁 - 即使与 SELECT
使用 WITH (NOLOCK)
查询提示的语句。
没有解决方法、技巧或其他查询提示可以使用,没有办法绕过它 - 您只需要知道并尊重它。一旦带有 ALTER TABLE
语句的事务被提交(或回滚),SCH-M
将被释放。
See the TechNet docs on Lock Modes详细讨论——还有其他情况(除了 ALTER TABLE
)当一个 SCH-M
锁被获取时(例如,当表被截断时)。
BU
锁(批量更新锁)也可以防止 SELECT
的发生——但是它会允许其他事务同时批量加载(但是它不允许任何其他内容)。
关于sql-server - 即使在应用 NOLOCK 之后,Select 语句也会等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20362002/