sql-server - SQL Server:Tablock,在选择之前还是之后锁定?
问题描述
在下面的示例中,使用时with (tablockx)
锁定是在选择确定最大值之前完成还是之后完成?插入到表“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
如果重要的话,我使用的是 SQL Server 2008 R2
解决方案
锁定是在选择确定最大值之前完成还是之后完成
之前,由查询优化器执行之前。毕竟,这样做也无济于事。这是您正在执行的语句的锁定方法。
插入语句插入表“table1”是否存在竞争条件
不,因为您正在使用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_whoIsActive
中从Adam Mechanic运行,您可以了解原因。具体来说,请查看您的插入会话。这将是像begin transaction declare @foo...这样的会话。blocking_session_id
sql_test
测试后不要忘记提交事务
推荐阅读
- hadoop - 创建 Hive 表时出错
- java-8 - 对象列表的排序列表
- html5-canvas - 画布 toDataURL 不适用于 GIF 或 JPEG
- javascript - Firebase 函数从其他文件导入函数 - javascript
- php - 是否可以提交没有序列号的数组?
- java - BigDecimal - MathContext.DECIMAL64 与 MathContext.DECIMAL128
- java - JSON解析。字符串作为对象的 Json 数组
- python - 为什么```print```不能在for循环中工作并且变量在Python中没有改变?
- c# - NetworkStream 在服务器关闭时读取
- django - Facebook 登录/图形 API - 在 localhost 和 http(不是 https)上入门