根据此article
Shared(S) - 用于不更改或更新数据的操作(只读操作),例如SELECT语句。
并根据此article
虽然保留了独占(X)锁,但在释放独占(X)锁之前,其他任何事务都不能获取该资源上的任何类型的锁(共享,更新或独占)。
因此,在第一个会话中,我运行以下代码:
begin tran
select *
from SomeTable with (xlock)
waitFor delay '00:00:05'
commit tran
当第一个事务运行时,我在第二个会话中运行以下代码:
begin tran
select * from SomeTable
commit tran
我立刻看到了select语句的结果。
为什么第二个事务不等待xlock被释放?
答案 0 :(得分:4)
X锁 保持到第一次交易结束。
但是,如果页面没有未提交的更改,SQL Server可以跳过S锁,以便第二个事务永远不会被第一个事务阻塞。
此处详细查看了此确切方案The Case of the Missing Shared Locks
答案 1 :(得分:1)
Martin Smith发布了一个有趣的答案,但在特定情况下,没有sql server优化。第二个事务不尝试获取共享锁的原因是READ_COMMITTED_SNAPSHOT
数据库选项为ON,在这种情况下,数据库引擎使用行版本控制,而不是使用锁来保护数据。
如果我在第二个事务中将READCOMMITTEDLOCK
表提示添加到select语句或从READ_COMMITTED_SNAPSHOT
设置中删除,则第二个事务会尝试获取共享锁并被第一个事务阻止。