1. DB LOCK이란?
MySQL에서 Lock(잠금)은 여러 트랜잭션이 동일한 데이터에 동시에 접근하려고 할 때 데이터 일관성을 유지하고 충돌을 방지하기 위한 메커니즘이다.
잠금을 사용하면 하나의 트랜잭션이 데이터를 변경하는 동안 다른 트랜잭션이 해당 데이터에 접근하지 못하게 할 수 있다.
MySQL에서의 잠금은 트랜잭션 관리와 밀접한 관계가 있으며, 아래의 몇개의 lock 종류가 존재한다.
2. LOCK의 종류
1) 공유잠금
공유잠금은 읽기 잠금(READ LOCK)으로 불리기도 한다. 데이터를 읽을 수는 있지만, 수정할수는 없다.
여러 트랜잭션이 동시에 같은 행에 대해 공유잠금을 얻을 수 있다. 즉 데이터를 읽는 것만 가능하며, 수정하려면 공유잠금을 해제하고 독점 잠금을 걸어야 한다.
ex) select * frolm table_name LOCK IN SHARE MODE;
2) 독점잠금
쓰기 잠금(WRITE LOCK) 이라고 불리며 데이터를 읽고 수정할 수 있는 권한을 제공한다.
한번에 하나의 트랜잭션만 독점 잠금을 얻을 수 있다. 즉, 독점잠금이 걸린 동안 다른 트랜잭션은 해당 데이터에 접근할 수 없다.
ex) select * from table_name FOR UPDATE;
3. 잠금의 범위
1) 테이블잠금(table lock)
mysql에서 지원하는 가장 기본적인 잠금 방식이다. 테이블 전체를 잠그는 방식이다. 테이블잠금에는 READ LOCK, WRITE LOCK이 있다.
READ LOCK : 테이블을 읽는 동안 다른 트랜잭션이 테이블을 수정할 수 없다.
WRITE LOCK : 테이블을 수정하는 동안 다른 트랜잭션이 테이블을 읽거나 수정할 수 없다.
LOCK TABLES table_name READ; -- 읽기 잠금
LOCK TABLES table_name WRITE; -- 쓰기 잠금
UNLOCK TABLES; -- 잠금 해제
2) 행장금(ROW LOCK)
특정 행 단위로 잠금을 걸 수 있는 LOCK이다. 트랜잭션에서 데이터를 변경하는 동안, 해당 행에만 잠금이 걸리기 때문에 다른 트랜잭션이 동일한 테이블의 다른 행에는 접근할 수 있다.
SELECT * FROM table_name WHERE condition FOR UPDATE; -- 해당 조건을 만족하는 행에 대해 독점 잠금
4. 잠금 대기와 교착상태
1) 잠금 대기(LOCK WAIT)
하나의 트랜잭션이 특정 자원에 대해 잠금을 걸고 있는 동안 다른 트랜잭션이 동일한 자원에 대해 잠금을 시도하면 잠금 대기가 발생한다. 이때, 다른 트랜잭션은 첫번째 트른잭션이 끝나기를 기다린다.
2) 교착상태(DEAD LOCK)
두 개 이상의 트랜잭션이 서로가 가지고 있는 잠금을 기다릴 때 발생하는 상태이다. 이런 경우 mysql은 자동으로 한쪽 트랜잭션을 롤백하여 교착상태를 해소한다.
교착 상태의 예:
- 트랜잭션 A가 테이블 X의 행 1을 잠그고, 트랜잭션 B는 테이블 Y의 행 2를 잠급니다.
- 트랜잭션 A가 행 2를 잠그려고 시도하고, 트랜잭션 B가 행 1을 잠그려고 시도하면 교착 상태가 발생합니다.