DB Lock
이란 데이터베이스에서 동시성 제어를 위해 사용하는 기능입니다.
DB Lock
은 트랜잭션을 수행하는 동안 데이터를 보호하고 다른 트랜잭션으로부터의 접근을 제한합니다.
DB Lock
은 데이터의 일관성과 무결성을 보장하는데 중요한 역할을 합니다. 하지만, DB Lock
은 잘못 사용하면 성능 저하나 교착 상태와 같은 문제를 야기할 수 있습니다. 따라서, DB Lock
을 적절하게 설계하고 관리하는 것이 필요합니다.
DB Lock에는 공유 Lock
과 배타적 Lock
이 있습니다.
공유 Lock
과 배타적 Lock
은 데이터베이스에서 동시성 제어를 위해 사용되는 기법입니다.
공유 Lock
은 여러 트랜잭션이 동일한 자원에 대해 읽기 작업을 수행할 수 있도록 허용하는 반면, 배타적 Lock
은 한 트랜잭션만이 자원에 대해 쓰기 작업을 수행할 수 있도록 허용합니다. 이렇게 함으로써, 데이터의 일관성과 무결성을 보장할 수 있습니다.
다른 트랜잭션이 잠긴 객체를 읽고 다른 공유 Lock
을 생성하는 것은 허용하지만, 쓰기나 배타적 Lock
을 생성하는 것을 허용하지 않는 잠금입니다.
동일한 행에 다른 트랜잭션을 생성하는 것을 허용하지 않는 잠금입니다.
예를 들어, A와 B가 같은 계좌에서 출금을 하려고 할 때, 공유 Lock
과 배타적 Lock
이 적용되는 과정은 다음과 같습니다.
조회
하기 위해 공유 Lock
을 걸고 읽기 작업을 수행합니다.조회
하기 위해 공유 Lock
을 걸고 읽기 작업을 수행합니다.배타적 Lock
을 요청합니다. 하지만 B가 아직 공유 Lock을 해제하지 않았으므로, A는 대기 상태가 됩니다.배타적 Lock
을 요청합니다. 하지만 A도 이미 배타적 Lock을 요청하고 있으므로, B도 대기 상태가 됩니다.이처럼, 공유 Lock과 배타적 Lock은 데이터베이스에서 동시성 제어
를 위한 중요한 역할을 합니다.
공유 Lock과 배타적 Lock의 핵심은 읽기 쓰기가 아니라 락 사이 호환 여부
입니다.
공유 Lock
은 같은 공유 Lock을 허용하기 때문에 읽기가 가능하고, 쓰기에 필요한 배타적 Lock을 불허하기 때문에 쓰기가 불가능 한 것이며,
배타적 Lock
은 락을 사용하는 읽기(Locking Reads)인 경우에는 불가능하며 락을 사용하지 않는 읽기(Consistent Nonlocking Reads)인 경우에는 가능합니다.
공유 Lock과 배타적 Lock의 잠금은 Auto Commit 이 비활성화
되거나, BEGIN 혹은 START TRANSACTION 명령
을 통해 트랜잭션이 시작된 상태에서만 잠금이 유지된다.
SELECT * FROM table_name WHERE id = 1 FOR SHARE;
SELECT * FROM table_name WHERE id = 1 FOR UPDATE;
InnoDB 스토리지 엔진을 사용하는 테이블에서 FOR UPDATE 혹은 FOR SHARE 절을 가지지 않는 SELECT 쿼리는 잠금 없는 읽기
가 지원된다. 따라서 특정 데이터가 FOR UPDATE 로 락이 걸린 상태라도 FOR UPDATE , FOR SHARE 가 없는 단순 SELECT 쿼리는 아무런 대기 없이 해당 데이터를 조회
할 수 있다.
DB 데드락이란 두 개 이상의 트랜잭션이 서로 상대방이 가지고 있는 자원을 기다리면서 무한정 대기하는 현상을 말합니다.
예를 들어, 트랜잭션 A가 테이블 X의 레코드를 잠근 상태에서 테이블 Y의 레코드를 요청하고, 트랜잭션 B가 테이블 Y의 레코드를 잠근 상태에서 테이블 X의 레코드를 요청하면, 두 트랜잭션은 서로가 잠근 자원을 해제할 때까지 기다리게 됩니다.
DB 데드락을 방지하거나 해결하기 위한 방법은 여러 가지가 있습니다. 대표적인 방법은 다음과 같습니다.
타임아웃 설정
트랜잭션이 일정 시간 동안 자원을 기다리다가 타임아웃이 발생하면, 트랜잭션을 롤백하고 다시 시도합니다. 이 방법은 간단하지만, 자주 발생하는 데드락에는 적합하지 않습니다.
자원 순서 부여
트랜잭션이 요청하는 자원에 순서를 부여하고, 트랜잭션은 순서대로 자원을 요청하도록 합니다.
예를 들어, 테이블 X와 Y에 1과 2의 순서를 부여하고, 트랜잭션은 1부터 2까지의 순서로만 자원을 요청하도록 합니다. 이 방법은 데드락을 완전히 방지할 수 있지만, 자원의 활용도가 낮아질 수 있습니다.
데드락 감지 및 복구
DBMS가 데드락을 감지하는 알고리즘을 실행하고, 데드락이 발생하면 특정 트랜잭션을 선택하여 롤백하고 다시 시도합니다. 이 방법은 데드락이 발생한 후에 해결하기 때문에, 성능 저하가 발생할 수 있습니다.