在SQL Server中是否可以在同一事务中的同一行上应用s锁和x锁?

时间:2016-03-03 07:47:55

标签: sql-server

在Repeatable Read隔离中,应用共享锁和独占锁,直到事务结束。现在考虑下面提到的查询,它在id列上有聚簇索引,在name和col1上有非聚簇索引

Set transaction isolation level repeatable read
begin transaction
update tableA
set name = 'abc'
where id = 1

select name, col
from tableA
where id = 1

commit transaction

在这种情况下,SQL Server如何处理锁定?将两个锁 - X锁和S锁在ID为1的行上或X锁将转换为S锁。

我在这里很困惑。有人可以更多地了解这种锁定行为。

2 个答案:

答案 0 :(得分:2)

好吧,因为它在同一个事务中,当然的SQL Server知道你已经更改/更新了什么,并且可以将它返回到你的{{1 }}。

SELECT独占锁仅阻止 OTHER 交易在更新时读取该数据。在X执行完毕之前,X锁将保持不变。

如果您在COMMIT之后暂停执行,然后切换到另一个SSMS窗口并在那里执行UPDATE,则阻止将无法读取正在更新的行

答案 1 :(得分:1)

您可以通过启用以下跟踪标志或查看sys.dm_tran_locks视图来检查锁定/保持锁定。

请勿在生产环境中运行这些跟踪标志。

traceflags将输出消息中获取/释放的锁。

在这个测试中,似乎它正在持有X锁并且还在同一个RID上获取S锁。 sys.dm_tran_locks的输出表明实际上只保存了X锁。

您的结果可能会有所不同。

DBCC TRACEON(1200,-1,3604);
SET transaction isolation level repeatable read
BEGIN TRAN
UPDATE dbo.Customer SET name = 'peter';
SELECT * FROM dbo.Customer WHERE id = 1

DBCC TRACEOFF(1200,-1,3604);
SELECT * FROM sys.dm_tran_locks WHERE request_session_id = @@SPID

COMMIT

traceflag的输出:

  

进程56获取DATABASE上的S锁:13 [PLANGUIDE](类bit0   ref1)结果:好的

     

进程56释放对DATABASE的锁定:13 [PLANGUIDE]

     

DBCC执行完成。如果DBCC打印出错误消息,请联系您的   系统管理员。

     

进程56获取对象的IX锁定:   13:1920061926:0(类bit2000000 ref1)结果:OK

     

进程56在PAGE:13:1:2150(类bit2000000)上获取IU锁定   ref0)结果:好的

     

进程56获取RID上的U锁:13:1:2150:0(类bit2000000   ref0)结果:好的

     

进程56在PAGE:13:1:2150(类bit2000000)上获取IX锁定   ref0)结果:好的

     

进程56获取RID上的X锁定:13:1:2150:0(类bit2000000   ref0)结果:好的

     

(1行受影响)

     

过程56在PAGE:13:1:2150上获取IS锁定   (类bit2000000 ref0)结果:确定

     

进程56获取RID上的S锁:13:1:2150:0(类bit2000000   ref0)结果:好的

     

(1行受影响)

     

进程56释放所有锁@ 00000002E54015A8

     

进程56完成释放所有锁@ 00000002E54015A8

     

进程56释放所有锁@ 00000002E54015A8

     

进程56完成释放所有锁@ 00000002E54015A8

     

进程56释放所有锁@ 00000002E54015A8

     

进程56完成释放所有锁@ 00000002E54015A8

     

进程56释放所有锁@ 00000002E54015A8

     

进程56完成释放所有锁@ 00000002E54015A8

     

进程56释放所有锁@ 00000002E54015A8

     

进程56完成释放所有锁@ 00000002E54015A8

     

进程56释放所有锁@ 00000002E54015A8

     

进程56完成释放所有锁@ 00000002E54015A8

     

进程56释放所有锁@ 00000002E54015A8

     

进程56完成释放所有锁@ 00000002E54015A8

     

(4行(s)受影响)DBCC执行完成。如果DBCC打印错误   消息,请与您的系统管理员联系。