편집 : @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
정확히 내가 필요한 것이라면 어떻게 나쁜 습관 입니까?