SQL Server에서 읽기 잠금은 어떻게 작동합니까?


17

다음과 같이 장기 실행 쿼리가 있다고 가정하십시오.

UPDATE [Table1]
SET [Col1] = 'some value'
WHERE [Col2] -- some clause which selects thousands of rows

위의 쿼리가 실행되는 동안 다음 쿼리가 실행된다고 가정하십시오.

SELECT *
FROM [Table1]

첫 번째 쿼리는 첫 번째 쿼리가 완료 될 때까지 두 번째 쿼리가 실행되지 못하게합니까? 그렇다면 첫 번째 쿼리는 두 번째 쿼리가 모든 행 또는 WHERE 절에 포함 된 행에서 실행되지 못하게합니까?

편집하다:

두 번째 쿼리가

SELECT [Col1], [Col2]
FROM [Table1]
WHERE [Col2] -- some clause whose matching elements overlap those from
             -- the clause in the first query and which has additional matching elements

답변:


14

난 당신이 읽을 것을 권장 SQL Server가 쿼리를 실행하는 방법에 대한 이해 가 읽는 방법에 대한 설명을 가지고 작업하는 방법과 잠금 작품을 쓴다.

10000ft 뷰는 다음과 같습니다.

  • 읽기 연산자는 데이터를 읽기 전에 읽은 데이터에 대한 공유 잠금을 얻습니다.
  • 쓰기 연산자는 데이터를 수정하기 전에 수정 한 데이터에 대한 독점 잠금을 획득합니다.
  • 데이터 잠금은 단지 문자열입니다. 데이터베이스와 객체에 의해 범위가 지정된 키의 해시
  • 잠금 관리자는 잠금 호환성 매트릭스 에 따라 부여 된 모든 잠금 목록을 유지하고 비 호환성을 감지합니다.
  • 호환되지 않는 요청은 차단할 수없는 권한 부여 요청이 해제 될 때까지 일시 중지됩니다.
  • 연산자는 잠금 계층 구조를 사용하여 더 높은 수준 (페이지 또는 테이블 수준, 파티션 수준 옵션 무시)에서 데이터를 읽거나 업데이트 할 의도를 선언합니다. 이를 통해 운영자는 모든 개별 행을 잠그지 않고 전체 테이블을 잠글 수 있습니다
  • 잠금 수명과 범위 잠금은 높은 격리 수준을 적용하는 데 사용됩니다.

이것은 실제로 빙산의 일각에 불과합니다. 주제는 광대하다. 귀하의 예에서 아무도 실제로 잠긴 내용에 대한 귀하의 질문에 답할 수있는 사람은 많지 않습니다. 물론 SELECT * FROM Table1 WHERE 절이 누락되어 사용 하고 있기 때문에 응용 프로그램을 발행해서는 안됩니다 *. 이것들은 나쁜 관행입니다. 그 이유는 무엇보다도 정확하게 경쟁을 막을 수 있기 때문입니다.

읽기 대 쓰기 잠금이 발생하면 행 버전 관리 및 스냅 샷 격리를 조사해야합니다. 행 버전 관리 기반 격리 수준 이해를 읽어보십시오 .


테이블의 모든 내용이 필요한 경우 (예 : 14 개의 행만 있음)? 그것이 SELECT * FROM Table1정확히 내가 필요한 것이라면 어떻게 나쁜 습관 입니까?
방위각

1
*테이블 구조가 변경되면 일반적으로 응용 프로그램이 중단되기 때문에 (예기치 않은 열이 결과로 표시됨) 자체적으로 나쁜 습관입니다.
Remus Rusanu

3

편집 : @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의 잠금에 대한 모든 내용은 여기를 참조하십시오 .


1
WITH (NOLOCK)이 경우 사용에 관한 경고 가 도움이 될 것입니다. 자세한 내용은 brentozar.com/archive/2011/11/…brentozar.com/archive/2013/02/… 를 참조하십시오 .
Max Vernon

3
아, WITH (NOLOCK)힌트는 커밋되지 않은 메모리에서 더티 페이지를 반환하지 않습니다. 실제로 작성자가 테이블에서 사용하는 페이지에 행을 업데이트하거나 추가하는 것을 차단하지 않고 테이블에서 (디스크상의 또는 메모리 내에서 캐시 된) 행을 읽습니다.
Max Vernon

2
혼란 스러워요. "첫 번째 쿼리가 두 번째 쿼리를 실행하지 못하게합니까?" "아니요", 두 번째 질문에 대한 대답은 "예"가 될 수 있습니까? 어떤 질문에 답하고 답을 넓힐 수 있습니까?
모든 거래의 존

많은 사람들을 수정합니다. 죄송합니다. 불분명 한 것이 있으면 알려주세요!
Avarkx
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.