【问题标题】:Why SQL Server unexpectedly stops issuing range locks为什么 SQL Server 意外停止发出范围锁
【发布时间】:2013-12-26 03:46:34
【问题描述】:

我对以下情况感到困惑:当超过访问表中的某些行数时,范围锁的发布意外地停止了。

简要说明:有一张具有唯一聚集索引的表;除了 PK 表包含不唯一的列。我们尝试使用可序列化(可重复读取 IL 不会发生)隔离级别从该表中选择所有值。一切都按预期进行(正如 msdn 所说:持有的 RangeS-S 锁的数量为 n+1,其中 n 是满足查询的行数。)直到超出某些行数限制。

我认为提供代码示例会更好:

if (exists (select * from information_schema.tables where table_name = 'T'))
    drop table T

create table T
(
    id int not null,
    val int not null
    primary key (id)
)

declare @numOfRow int = 10000 -- after 6232 range locks doesn't issued

begin tran
    declare @i int = 0
    while @i < @numOfRow 
    begin
        insert into T
        values (@i, @i)

        set @i = @i + 1
    end
commit

--set transaction isolation level repeatable read
set transaction isolation level serializable
begin tran
    select *
    from T -- with (holdlock)

    select *
    from sys.dm_tran_locks
    where request_session_id = @@SPID
commit

对于我来说,如果我将@numOfRow 设置为等于 6233 并且更大,则不会发出范围锁定。

@@VERSION = Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64)   Jul  9 2008 14:17:44   Copyright (c) 1988-2008 Microsoft Corporation  Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) 

【问题讨论】:

    标签: sql-server sql-server-2008 locking isolation-level


    【解决方案1】:

    它确实获得了范围锁。

    因为每个锁都会消耗内存,lock escalation 通常会在获得 5,000 个锁之后的某个时间点启动。

    锁升级会导致更细粒度级别的锁更少。

    要查看此内容,您可以添加dbcc traceon(1200,3604,-1)

    记得用dbcc traceoff(1200,3604,-1)再次关闭标志

    【讨论】:

      猜你喜欢
      • 2013-01-31
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 1970-01-01
      • 2015-06-01
      • 2023-01-22
      相关资源
      最近更新 更多