WITH(NOLOCK)
SQL Server 에서 WITH(NOLOCK) 의 힌트를 제공합니다.
WITH(NOLOCK) 의 의미는 다음과 같습니다.
락이 잡혀있는 데이터에 접근하여 데이터를 읽는다.
락이 잡혀있다는 말은 트랜잭션 중이라는 의미이고, 트랜잭션 내에서 데이터는 변경된 데이터를 읽습니다.
즉 잠금을 무시한 Dirty Read 이며 트랜잭션이 Rollback 되는 경우에는 잘못된 데이터를 읽을 수 있게 됩니다.
그럼에도 불구하고 WITH(NOLOCK) 옵션은 SELECT 가 대기해야 하는 불상사를 막을 수 있기 때문에 자주 사용됩니다.
WITH(NOLOCK) 테스트
WITH(NOLOCK) 이 없는 일반 구문을 사용하는 경우,
C1 = 1 의 데이터에 대해서 LOCK 이 잡혀있기 때문에 SELECT 는 대기하게 됩니다.
세션1 |
세션2 |
BEGIN TRANSACTION UPDATE T1 SET C1 = 2 WHERE C1 = 1 |
|
SELECT * FROM T1 |
sp_who2 명령어를 사용하면 SELECT 문이 대기하고 있는 것을 확인할 수 있습니다.
이번에는 WITH(NOLOCK) 을 사용한 쿼리입니다.
세션 1에서 트랜잭션이 끝나지 않았지만, 잠금을 무시한 Dirty Read 데이터를 읽기 때문에 2라는 값이 출력되었습니다.
만약 세션1 에서 Rollback 을 수행하게 되는 경우 세션2에서 읽은 데이터는 잘못된 값이 될 수 있습니다.
세션1 |
세션2 |
BEGIN TRANSACTION UPDATE T1 SET C1 = 2 WHERE C1 = 1 |
|
SELECT * FROM T1 WITH(NOLOCK) |
잠금 모드
SQL Server 는 여러가지 잠금 모드를 제공하고 있습니다.
그중 많이 사용되는 잠금에 대해서 보겠습니다.
잠금 모드 |
설명 |
S ( 공유 ) |
SELECT 와 같은 읽기 작업에 사용 다른 잠금과 공유가 가능 |
U ( 업데이트 ) |
업데이트시 발생하는 교착을 방지하기 위해 사용 |
X ( 베타 ) |
DML 과 같은 데이터 수정작업에 사용 여러 개의 작업이 같은 데이터에 대해 동시에 이루어지지 못하게 하기 위해 사용 |
S 락은 공유 잠금이기 때문에 먼저 세션2에서 SELECT 구문을 수행하였더라도 세션1에서 UPDATE 를 할 수 있습니다.
세션1 |
세션2 |
BEGIN TRANSACTION SELECT * FROM T1 |
|
BEGIN TRANSACTION UPDATE T1 SET C1 = 2 WHERE C1 = 1 |
'SQL Server > SQL Server 기타' 카테고리의 다른 글
[MSSQL] VLF 개수에 따른 성능 차이 (0) | 2019.08.06 |
---|---|
[MSSQL] VARCHAR(MAX) vs VARCHAR(N) / VARCHAR(MAX) 의 단점 (0) | 2019.06.24 |
[MSSQL] Batch Requests/sec 와 Transactions/sec 의 차이점 (1) | 2019.06.03 |
[MSSQL] CheckPoint (검사점) 주기 설정하기 (0) | 2019.06.03 |
[MSSQL] 클러스터 인덱스, 넌 클러스터 인덱스, 클러스터 인덱스 + 넌 클러스터 인덱스 구조 (1) | 2019.05.23 |