편집 : @MaxVernon이 지적했듯이 다음은 NOLOCK을 사용하는 제안이 아니며 , 거래 수준을 설정 READ UNCOMMITED하고 부정적인 의미 NOLOCK가 처음에 나오는 것보다 낫다는 것을 언급했을 것 입니다. 원래 게시 된대로 :
빠르고 간단한 방법은 "예. 특정 인덱스 힌트가 지정되지 않은 경우 ( NOLOCK , 때로는"dirty read "라고 함) 또는 두 번째 쿼리의 트랜잭션 격리 수준이 READ UNCOMMITED(동일하게 작동)로 설정 되지 않는 한 첫 번째 쿼리는 두 번째 쿼리를 차단합니다 . 아니 그렇지 않아."
질문에 제공된 추가 세부 사항에 대해 상호 배타적이거나 달리 독점적 인 WITH두 번째 조항을 포함하는 SELECT경우 두 쿼리 간의 상호 작용은 거의 동일합니다.
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'Foo'
AND type = 'U' )
BEGIN
--DROP TABLE dbo.Foo;
CREATE TABLE dbo.Foo
(
Foo_PK BIGINT IDENTITY( 1, 1 ) NOT NULL,
PRIMARY KEY ( Foo_PK ),
Bar BIT,
x BIT,
y BIT,
z BIT
);
CREATE NONCLUSTERED INDEX IX_Foo_x
ON dbo.Foo ( x );
INSERT INTO dbo.Foo ( Bar, x, y, z )
VALUES ( 1, 1, 1, 1 ), ( 0, 0, 0, 0 );
END;
GO
BEGIN TRANSACTION;
UPDATE dbo.Foo
SET y = 0
WHERE x = 1;
-- COMMIT TRANSACTION;
별도의 세션에서 다음을 실행하십시오.
SELECT *
FROM dbo.Foo WITH ( NOLOCK );
GO
SELECT *
FROM dbo.Foo;
sp_lock가급적 또 다른 별도 세션에서을 실행하여 현재 보유중인 잠금을 검사 할 수 있습니다 .
EXECUTE dbo.sp_lock;
당신은 볼 수 KEY타입의 잠금에 삽입 트랜잭션을 수행하는 SPID에 의해 개최되고 X있지 다른와 혼동 (독점) 모드 IX(의도-전용) 잠금. 로크 문서는 상태가 나타내는 KEY잠금 범위 별이다, 또한 내부 그래서 원래의 질의의 범위 내로 할 수 있음을 포함 삽입하거나 데이터를 변경하여 해당 항목을 갱신하는 다른 트랜잭션을 방지한다. 개최되는 잠금 자체가 독점, 제 쿼리에서 리소스에 대한 액세스 방해하는 어떤 다른 동시 트랜잭션을. 실제로 열의 모든 행은 첫 번째 쿼리에서 지정한 범위 내에 있는지 여부에 관계없이 잠 깁니다.
S로크가 제 2 세션에 의해 유지되는 것, 따라서 WAIT까지 X로크 지우고 다른 방지 X(또는 U두번째 세션이 존재 정당화의 판독 동작을 완료하기 전에 다른 동시 SPID로부터 해당 자원에 촬영되는) 잠금 S잠금.
이제 명확성을 위해 편집 : 여기에 언급 된 위험에 대한 간략한 설명에서 더티 리드가 무엇인지 오해하지 않는 한 ... 편집 3 : 방금 내가 배경 체크 포인트의 영향을 고려하지 않는다는 것을 깨달았습니다. 아직 커밋되지 않은 트랜잭션이 디스크로 전송되었으므로 설명이 잘못되었습니다.
두 번째 쿼리에서 첫 번째 배치는 커밋되지 않은 데이터를 반환 할 수 있습니다 (이 경우). 기본 트랜잭션 격리 수준에서 실행되는 두 번째 배치 READ COMMITED는 첫 번째 세션에서 커밋 또는 롤백이 완료된 후에 만 반환됩니다.
여기에서 쿼리 계획 및 관련 잠금 수준을 볼 수 있지만 SQL Server의 잠금에 대한 모든 내용은 여기를 참조하십시오 .
SELECT * FROM Table1정확히 내가 필요한 것이라면 어떻게 나쁜 습관 입니까?