본문 바로가기

개발/Database

Lock

DBMS는 각 트랜잭션의 오퍼레이션 별로 적당한 수준의 Lock을 자동으로 설정한다. 가장 기본이 되는 Lock 모드는 공유 Lock와 배타적 Lock이다. 

 

- 공유 Lock

공유 Lock은 데이터를 읽고자 할 때 사용하며 다른 공유 Lock와는 호환되지만 배타적 Lock와는 호환되지 않는다. 여기서 호환됨은 하나의 리소스에 두개 이상의 락을 동시에 설정할 수 있음을 말한다. 다른 사용자가 동시에 한 리소스를 읽을 수는 있으나 변경은 불가능하다. 반대로 다른 사용자가 읽고 있는 리소스를 동시에 읽을 수는 있어도 사용중인 리소스를 동시에 읽을 수는 없다.

 

- 배타 Lock

데이터를 변경하고자 할 경우 사용되며 트랜잭션의 완료 시까지 유지된다. 해당 락이 해제되기 전까지 다른 트랜잭션은 해당 리소스에 접근할 수 없다. 다른 트랜잭션에 의해 락이 설정된 리소스는 그것이 공유 락이든 배타적 락이든 동시에 설정할 수 없다.

 

- 블로킹

블로킹이란 락의 경합이 발생하여 작업을 진행하지 못하고 멈춰 있는 상태를 말한다. 공유 락끼리는 호환되어 블로킹이 발생하지 않는다.

블로킹 상태를 해소하는 방법은 커밋 또는 롤백 뿐이다. 

 

- 교착상태

교착상태는 두 세션이 각 락을 설정한 리소스를 서로 액세스하기 위해 마주보고 있는 상황을 말한다. 교착 상태가 발생하면 DBMS가 한 세션에 에러를 발생시켜 문제를 해결한다. SQL Server의 경우 갱신 락을 사용하여 교착상태의 발생 가능성을 줄일 수 있다.

 

- SQL Server

- 공유 Lock

다음 레코드가 읽히면 공유 락이 해제된다. 단, 기본 트랜잭션의 격리성 수준에서만 그렇다.(Read Commited) 격리성 수준을 변경하지 않고 트랜잭션 내에서 공유 락이 유지되도록 하려면 아래와 같이 테이블 힌트로 holdlock을 지정하면 된다. 

 

- 배타적 Lock

데이터를 변경하고자 할 경우 사용되며 트랜잭션의 완료 시까지 유지된다. 해당 락이 해제되기 전까지 다른 트랜잭션은 해당 리소스에 접근할 수 없다. 다른 트랜잭션에 의해 락이 설정된 리소스는 그것이 공유 락이든 배타적 락이든 동시에 설정할 수 없다.

 

- 갱신 Lock

갱신 락 기능을 사용하려면 updlock 힌트를 지정하면 된다. 갱신 락이 설정되어 있을 경우 두번째 트랜잭션은 첫번째 트랜잭션의 배타적 락으로 전환되었다가 이를 해제할 때까지 기다려야 한다. 

 

- 의도 Lock

특정 로우에 락을 설정하면 그와 동시에 상위 레벨 개체에도 내부적으로 의도 락이 설정된다. 락을 설정하려는 개체의 하위 레벨에서 선행 트랜잭션이 어떤 작업을 수행중인지 알리는 용도로 사용되며 일종의 푯말이라고도 할 수 있다. 

 

- 스키마 Lock

테이블 스키마에 대한 의존적인 작업을 수행할 때 사용한다. 

Sch-S(Schema Stability) : SQL을 컴파일하면서 오브젝트 스키마를 참도할 때 발생하며 읽는 스키마 정보가 수정되거나 삭제되지 못하도록 한다.

Sch-M(Schema Modification) : 테이블 구조를 변경하는 DDL문을 수행할 때 발생하며 수정 중인 스키마 정보를 다른 세션이 참조하지 못하도록 한다.

 

- Bulk Update Lock 

테이블 락의 일종으로 테이블에 데이터를 벌크 카피할때 발생한다. 병렬 데이터 로딩을 허용하지만 일반적인 트랜잭션 작업은 허용되지 않는다.

 

- Oracle Lock

- 로우 Lock

로우 락은 항상 항상 배타적이다. 트랜잭션에 의해 설정되며 트랜잭션이 커밋 또는 롤백할 때까지 다른 트랜잭션은 해당 로우를 변경할 수 없다. 

 

- 테이블 Lock

한 트랜잭션이 로우 Lock을 얻는 순간 해당 테이블에 대한 테이블 Lock도 동시에 얻는다. 그럼으로써 현재 트랜잭션이 갱신 중인 테이블에 대한 호환되지 않은 DDL 오퍼레이션을 방지한다.