Sql server SQL Server:Tablock,在选择之前还是之后锁定?
在下面的示例中,当将Sql server SQL Server:Tablock,在选择之前还是之后锁定?,sql-server,sql-server-2008-r2,Sql Server,Sql Server 2008 R2,在下面的示例中,当将与(tablockx)一起使用时,锁定是在select确定最大值之前还是之后完成的?是否存在将insert语句插入表“table1”的竞争条件,或者是否保证@foo将包含在表中找到的最大值,直到提交或回滚事务 begin Transaction declare @foo int = (select max(col1) from table1 with (tablockx)) -- Is it possible that max(col1) can be > @foo
与(tablockx)
一起使用时,锁定是在select确定最大值之前还是之后完成的?是否存在将insert语句插入表“table1”的竞争条件,或者是否保证@foo将包含在表中找到的最大值,直到提交或回滚事务
begin Transaction
declare @foo int = (select max(col1) from table1 with (tablockx))
-- Is it possible that max(col1) can be > @foo here?
Commit Transaction
如果重要的话,我使用的是SQLServer2008R2
锁定是否在选择确定最大值之前完成,或
之后
在执行之前,由查询优化器执行。毕竟,这样做也无济于事。这是您正在执行的语句的锁定方法
在表中插入insert语句时是否存在竞争条件
“表1”
不,因为您使用的是TABLOCKX
,而不仅仅是TABLOCK
。后者允许共享锁,但您通过TABLOCKX
获得表上的独占锁
是否保证@foo将包含在
表,直到提交或回滚事务
是的,所有其他事务都将被阻止(删除、插入、更新等)
测试
要测试这一点,请创建一个表并插入一个值
create table t1_delete (col1 int)
insert into t1_delete
values (1)
go
接下来,在一个SSMS面板中运行代码,但注释掉COMMIT TRAN
begin Transaction
declare @foo int = (select max(col1) from t1_delete with (tablockx))
-- Is it possible that max(col1) can be > @foo here?
select @foo
--Commit Transaction
现在,在新建SSMS窗口中尝试插入一个新值或其他任何内容
insert into t1_delete
values(2)
您将注意到查询旋转。如果在另一个查询窗口中运行exec sp\u whoIsActive
,您可以看到原因。具体来说,请查看插入会话的阻塞会话\u id
。这将是一个与sql\u test
类似begintransaction declare@foo….的会话
不要忘记在测试后提交事务Tablockx将获取一个独占锁,该锁在提交或回滚事务时释放。因此,您的评论区域将被阻止。我知道它抓住了一个锁,只是不确定它是在确定select将返回哪些行之前还是之后。我认为逻辑上必须在执行查询之前,但我想确定一下。