공유 락(Shared Lock)과 배타 락(Exclusive Lock)
- 공유 락(읽기 락)
- 공유 락이 걸린 데이터는 다른 트랜잭션에서 읽기만 가능하고 쓰기는 불가능하다.
- 즉, 공유 락이 걸린 데이터에 대해서 다른 트랜잭션도 똑같이 공유 락을 획득할 수 있다. 단, 배타 락은 획득할 수 없다.
- 따라서 공유 락을 사용하여 조회한 데이터는 트랜잭션 내내 변경되지 않음이 보장된다.
- 배타 락(쓰기 락)
- 배타 락이 걸린 데이터는 다른 트랜잭션에서 읽기와 쓰기 모두 불가능하다.
- 즉, 배타 락이 걸린 데이터에 대해서 다른 트랜잭션은 공유 락, 배타 락 둘 다 획득할 수 없다.
- 즉, 배타 락을 획득한 트랜잭션은 해당 데이터에 대한 독점권을 갖는 것이다.
정리해보면 아래 표와 같이 배타 락이 개입하는 경우 양립이 불가능해진다.
공유 락 | 배타 락 | |
공유 락 | 허용 | 대기 |
배타 락 | 대기 | 대기 |
- 공유 락이 걸린 데이터에 대해 공유 락을 획득하는 것은 허용된다.
- 공유 락이 걸린 데이터에 대해 배타 락을 획득하려면 대기해야 한다.
- 배타 락이 걸린 데이터에 대해 공유 락을 획득하려면 대기해야 한다.
- 배타 락이 걸린 데이터에 대해 배타 락을 획득하려면 대기해야 한다.
이러한 특성으로 인해 데드락이 발생할 수 있다.
MySQL에서의 공유 락과 배타 락
공유 락을 획득하려면 SELECT FOR SHARE를 사용하면 되고, 배타 락을 획득하려면 SELECT FOR UPDATE를 사용하면 된다.
SELECT * FROM user WHERE user_id = 1 FOR SHARE; // 공유 락 획득
SELECT * FROM user WHERE user_id = 1 FOR UPDATE; // 배타 락 획득
데드락
데드락은 서로가 점유하고 있는 자원에 대해 무한정 대기하고 있는 상황을 의미한다.
데드락은 트랜잭션 격리 수준이 SERIALIZABLE인 경우 자주 발생할 수 있다.
- 예를 들어 트랜잭션 1이 데이터 1을 조회하며 읽기 락을 획득했고, 트랜잭션 2도 동시에 데이터 1을 조회하며 읽기 락을 획득했다고 가정하자.
- 트랜잭션 1이 데이터 1을 수정하기 위해 배타 락을 획득해야 하는데, 트랜잭션 2가 읽기 락을 갖고 있어서 대기한다.
- 마찬가지로 트랜잭션 2도 데이터 1을 수정하기 위해 배타 락을 획득해야 하는데, 트랜잭션 1이 읽기 락을 갖고 있어서 대기한다.
- 즉 트랜잭션 1과 트랜잭션 2는 서로의 읽기 락이 해제될 때까지 무한정 대기한다. 이를 데드락이라 한다.
Reference
'CS > Database' 카테고리의 다른 글
[Real MySQL] 5. 트랜잭션과 락 (2) | 2024.02.27 |
---|---|
[Real MySQL] 4.아키텍처 - InnoDB 스토리지 엔진 아키텍처 (0) | 2024.02.26 |
[Real MySQL] 4. 아키텍처 - MySQL 엔진 아키텍처 (0) | 2024.02.26 |
MySQL의 MVCC(Multi Version Concurrency Control) (0) | 2024.02.07 |
트랜잭션과 격리 수준 (1) | 2024.01.16 |