2013-12-09 2 views
2

다음과 같은 상황에 의아해합니다. 액세스 된 테이블의 일부 행 수가 초과되면 범위 잠금이 발생하는 것이 놀라 울 정도로 멈 춥니 다.SQL Server가 예기치 않게 범위 잠금 발급을 중지하는 이유

간략한 설명 : 고유 한 클러스터 된 인덱스가있는 테이블이 하나 있습니다. PK 테이블에는 고유 한 컬럼이 없습니다. 이 테이블의 모든 값을 직렬화 가능 (반복 가능 읽기 IL에서는 발생하지 않음) 격리 수준으로 선택하려고합니다. 모든 행 수가 제한을 초과 할 때까지 모든 것이 예상대로 진행됩니다 (msdn에 의하면 : 보유 된 RangeS-S 잠금 수는 n + 1이고 n은 쿼리를 만족하는 행 수입니다). 내가 @numOfRow는 6233 아무 범위 잠금이 발행되지 않습니다 이상으로 동일 설정하면 나에게

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 

:

가 나는 예 더 나은 코드를 제공 할 것입니다 생각합니다.

@@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) 

enter image description here

답변

2

가 범위 로크를 획득 않는다.

각 잠금 장치가 메모리를 소비하므로 lock escalation은 일반적으로 5,000 개의 잠금을 획득 한 후 어느 시점에서 시작할 수 있습니다.

잠금 에스컬레이션은 덜 세밀한 수준에서 더 적은 수의 잠금을 발생시킵니다.

dbcc traceon(1200,3604,-1)

enter image description here

dbcc traceoff(1200,3604,-1)

다시 플래그를 해제하는 것을 잊지 추가 할 수 있습니다이를 보려면