SELECT문 WITH(???LOCK) 절


출처 : http://zephome.tistory.com/141 

평소에 잘모르고 무심코 사용을 했었는데 다시 한번 생각해보게 되네요.
DBguide.net Q&A 게시판

Question

안녕하세요?
막 DB를 만지기 시작한 초보입니다.
다름이아니고 궁금한게 있어서 그런데요,
쿼리문을 쓰다보면 쿼리문 뒤에 With (***Lock) 옵션을 붙이잖아요~
예를들어
select * from dbo.Test    with (nolock)
혹은
update dbo.Test  with (updlock) set a=10

이런식으로 NOLOCK, ROWLOCK, UPDLOCK 등을 쓰는걸 봤는데요,
각각의 간략한 의미와 어떤 문에 붙여야하는지 어드바이스 좀 해주세요 !
예를들어
 "  NOLOCK 은 SELECT  문에서 LOCK 걸리는걸 막아준다  "  같은거요~
부탁드립니다!



Answer

오랫만에 인사드립니다.
제가 3개월간의 파견근무를 마치고 다시 회사로 돌아왔습니다.
그동안 MSSQL 분야 질문에 대한 답변을 소홀하게 했던 점 송구하게 생각합니다.
다른 분들이 잘 설명을 주셨는데,사족을 좀 붙여보고자 합니다.

1) NOLOCK (=READUNCOMMITTED)
MS SQL 서버의 경우 데이터의 일관성을 보장하기 위해 SELECT 작업을 할 때도 공유잠금(S)을 설정합니다.
이러한 경우,
SELECT 하는 동안에는 동일한 대상(행,페이지,테이블 등)에 다른 spid에서 배타적잠금(X)를 설정할 수 없습니다.
하지만, 이러한 특성 때문에 동시사용자가 많은 경우에서 차단(Blocking) 현상이 발생할 가능성이 있습니다.
즉,  
1) 임 배타적잠금이 걸린 대상에 대해서는 공유잠금(S)을 설정할 수 없기 때문에 차단이 발생하는 경우와,
2) 공유잠금이 걸린 대상에 배타적잠금을 설정하는 경우가 모두 차단현상이 발생하는 문제가 발생합니다.
이를 해결하기 위해
SELECT 쿼리의 FROM 절 다음의 각 테이블의 NOLOCK 옵션을 사용하게 되면
SELECT 쿼리를 할 때 공유잠금을 설정하지 않고 데이터를 읽게 됩니다.
이를 통해, 위의 두 가지 경우 차단현상이 발생하지 않고 작업을 수행할 수 있습니다.

2) ROWLOCK
SQL Server는 기본적으로 행 단위 잠금을 사용합니다.
다만, 내부적인 기준에 따라 행 단위 잠금보다 더 상위 단위(페이지, 테이블) 대상에 대해서 잠금을 설정해야 한다면 페이지잠금, 테이블 잠금을 자동적으로 승격하여 사용하게 됩니다.
이러한 경우, 특별하게 사용자가 이를 통제하여 행단위잠금을 강제하기 위해서 사용하는 옵션입니다.
이 옵션은 채번과 같은, 매우 고유한 업무에 대해서만 제한적으로 사용되어야 합니다.

3) UPDLOCK
UPDLOCK은 SELECT하는 대상에 대해 곧바로 배타적잠금을 설정할 예정인 경우, SELECT하는 대상에 다른 세션에서 배타적 잠금을 설정하지 못하도록 통제하기 위해서 사용합니다.
즉 
1) SPID 51 : SELECT * FROM 테이블
2) SPID 52 : UPDATE 테이블 SET...
3) SPID 51 : UPDATE 테이블 SET...
이러한 경우 51번의 업데이트 작업은 52번의 업데이트 작업이 완료될 때까지 차단되고 대기해야 합니다.
이 때
1) SPID 51 : SELECT * FROM 테이블 WITH(UPDLOCK)
2) SPID 52 : UPDATE 테이블 SET...
3) SPID 51 : UPDATE 테이블 SET...
을 사용하면, 
52번 업데이트 작업이 51 번에서 설정된 UPDLOCK으로 인해 차단되고, 3번 UPDATE 작업은 계속하여 진행할 수 있게 됩니다.

이러한 잠금과 관련한 옵션은 데이터 일관성과 병행성이라는 두 마리 토끼를 잡기 위해 노력하면서, 데드락과 같은 문제가 발생하지 않도록 하기 위해, 각 업무환경에 따라 매우 주의하여 사용되어져야 합니다.
감사합니다.

P.S> 추가적인 질문은 언제든지 게시판에 올려 주시면 됩니다