SQL Server 2008 R2 Dirty 읽기-원자가 아닌 방법?


11

"더러운"더티 읽기가 커밋되지 않은 읽기 격리 수준에 도달 할 수 있는지 궁금 합니다. 업데이트되었지만 아직 커밋되지 않은 행은 볼 수 있지만 다음을 이해합니다.

  1. 행이 부분적으로 업데이트 된 것으로 나타날 수 있습니까? 즉 일부 열이 업데이트되고 일부가 업데이트되지 않습니까?
  2. 단일 열이 부분적으로 업데이트 된 것처럼 보일 수 있습니까? 예를 들어, 완전히 업데이트되고 실제로 4000 개의 문자가 포함되어 있다고 가정하는 varchar (4000) 열이있는 경우. 이전 상태의 2k 문자와 새로운 상태의 2k 문자를 읽을 수 있습니까? 길이가 8k보다 큰 varchar (max)는 어떻습니까?

업데이트 : 약간의 토론 후에 최소한의 합의는 열 크기가 8KB보다 크면 열 자체 내에서도 더티 읽기가 가능하다는 것입니다.

답변:


7

수정 됨 판독 후 주석에서 MSDN 포럼 링크를 매우 흥미로운.

격리 수준에 관계없이 두 명의 사용자가 단일 페이지를 동시에 업데이트 하거나 일부 사용자가 부분적으로 업데이트 된 페이지를 읽을 수 없습니다. Col3이 17 바이트에서 시작한다고 헤더가 표시된 페이지를 SQL Server가 처리하는 방법을 상상해보십시오. 그러나 행의 일부가 아직 업데이트되지 않았기 때문에 실제로는 25 바이트에서 시작합니다. 데이터베이스가 처리 할 수있는 방법이 없습니다.

그러나 8k보다 큰 행의 경우 여러 페이지가 사용되므로 절반으로 업데이트 된 열이 가능합니다. 링크가 끊어진 경우 MSDN 링크에서 복사 한 후이 쿼리를 한 창에서 시작하십시오.

if object_id('TestTable') is not null
    drop table TestTable
create table TestTable (txt nvarchar(max) not null)
go
insert into TestTable select replicate(convert(varchar(max),
    char(65+abs(checksum(newid()))%26)),100000)
go 10
update TestTable set txt=replicate(convert(varchar(max),
    char(65+abs(checksum(newid()))%26)),100000)
go 100000

테이블을 만든 다음 같은 문자 100.000x의 문자열로 업데이트합니다. 첫 번째 쿼리가 실행되는 동안 다른 창에서이 쿼리를 시작하십시오.

while 1=1 begin
 if exists (select * from TestTable (nolock) where left(Txt,1) <> right(Txt,1))
    break
end

절반 업데이트 된 열을 읽으면 두 번째 쿼리가 중지됩니다. 즉, 첫 번째 문자가 마지막 문자와 다른 경우입니다. 절반으로 업데이트 된 열을 읽을 수 있음을 증명하면서 빠르게 완료됩니다. nolock힌트 를 제거하면 두 번째 쿼리가 완료되지 않습니다.

놀라운 결과! (nolock)XML이 잘못되어 반 업데이트 된 XML 열이 보고서를 손상 시킬 수 있습니다.


1
이것은 social.msdn.microsoft.com/Forums/en-US/transactsql/thread/…에 따르면 항상 사실이 아니지만 부분적으로 업데이트되는 열 유형은 여전히 ​​미스터리입니다.

@Andomar AFAIK 래치는 부분적으로 업데이트 된 페이지를 읽지 못하지만 NCI에서 일부 열 값을 읽었지만 CI에서 열을 검색하기 위해 책갈피 조회를 수행 한 경우 어떻게됩니까? 에서 NOLOCK나는 확신 NCI 열이 한 행의 버전 만 다른 버전의 CI 출신 상황을 설계 할 수있을 것이다. 또한 오프 행 데이터 및 로브 페이지는 데이터 페이지의 래치로 보호되지 않습니다.
Martin Smith

1
@Martin : 동의 nolock합니다. 원래 행을 찾지 못하는 자체 조인을 보았습니다 . 그러나 필드 또는 행의 단일 읽기는 일관되어야합니다.
Andomar

1
행의 열이 여러 페이지에 걸쳐 있지 않은 경우 @Andomar. 내 링크를 참조하십시오.

2
Michael은 원래 답변이 거의 없었기 때문에 실제로 CW 여야합니다. Michael은 현재 답변의 요지를 제공했습니다. 질문에 대한 귀하의 의견은 여전히 ​​수정 된 답변에 동의하지 않습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.