当SQL Server Books在线时说 “一旦读取操作完成 ,资源上的共享(S)锁就会被释放 ,除非事务隔离级别设置为可重复读取或更高,或者是锁定提示用于在事务期间保留共享(S)锁。“
假设我们在默认隔离级别(Read Committed)上讨论的是没有显式事务的行级锁定,那么“ 读取操作 ”会引用什么至?
注意:我需要知道的原因是我们有一个由数据层Web服务生成的第二个只读select语句,它创建页级共享读锁,由于与行级冲突而生成死锁来自复制程序的独占更新锁,用于更新服务器。 select语句相当大,有许多子选择,一个DBA建议我们重写它以将其分解为多个较小的语句(较短的运行部分),“减少锁定持有的时间”。因为这假设共享读锁一直保持到完成的select语句结束,如果这是错误的(如果在读取行或读取页面时释放锁),那么该方法将不会产生任何影响.... / p>
答案 0 :(得分:4)
实际观察非常有趣,你可能想要启动探查器并跟踪一些简单查询的锁定获取/释放。我做了一段时间回来,它是这样的: 获取第1页 获得第1行 获得第2行 发布第1行 获得第3行 发布第2行 获取第2页 发布第1页 ...
我可能不是100%正确,但这基本上是方法。因此,在读取行之后释放锁定,或者可能更正确地在获取下一行锁定之后释放锁定。我怀疑这可能与保持一致的遍历状态有关。
答案 1 :(得分:1)
我不相信它同时获得两个页面级锁。我认为它只会出现在分析器中,因为事件发生得如此之快。如果它像您怀疑的那样发生,总会有两个页面级锁,但是当使用共享锁运行大型查询时,我有时会看到两个页级锁,有时通过此查询看到一个:
SELECT *
FROM sys.dm_tran_locks
WHERE request_session_id = <SPID>
所以,我认为正在发生的事情是:
两个结果是有时在sys.dm_tran_lock查询中。我看到两个PAGE锁定,有时一次和几次三次......取决于同时操作期间发生的更快。
答案 2 :(得分:0)
关于具体文档,我发现了这一点
如果将READ_COMMITTED_SNAPSHOT设置为OFF(SQL Server的默认设置), 数据库引擎使用共享锁来防止其他事务 在当前事务运行读取时修改行 操作。共享锁还阻止语句读取行 被其他交易修改,直到另一笔交易被 完成。 共享锁类型确定何时将其释放。 在处理下一行之前释放行锁。页面锁 在读取下一页时释放,并释放表锁 语句结束时。