트랜잭션 격리 수준
트랜잭션 격리 수준
트랜잭션 격리수준(isolation level)이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다. 즉, 간단하게 말해 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것이다.
트랜잭션 동시 실행 문제
트랜잭션을 동시 실행할 때 생기는 문제는 아래와 같이 크게 3가지로 나뉜다.
- 오손 읽기(dirty read)
- 반복 불가능 읽기(non-repeatable read)
- 유령 데이터 읽기(phantom read)
오손 읽기
오손 읽기는 읽기 작업을 하는 트랜잭션1이 쓰기 작업을 하는 트랜잭션2가 작업한 중간 데이터를 읽기 때문에 생기는 문제이다.
작업 중인 트랜잭션2가 어떤 이유로 작업을 철회(rollback)할 경우 트랜잭션1은 무효가 된 데이터를 읽게 되고 잘못된 결과를 도출한다. 이 현상을 오손 읽기라고 한다.
반복 불가능 읽기
반복 불가능 읽기는 트랜잭션1이 데이터를 읽고 트랜잭션2가 데이터를 쓰고(UPDATE), 트랜잭션1이 다시 한 번 데이터를 읽을 때 생기는 문제이다. 즉, 트랜잭션1이 읽기 작업을 다시 한번 반복할 경우 이전의 결과가 반복되지 않는 현상을 반복 불가능 읽기 라고 한다.
유령 데이터 읽기
유령 데이터 읽기는 트랜잭션 1이 데이터를 읽고 트랜잭션 2가 데이터를 쓰고(INSERT) 트랜잭션 1이 데이터를 다시 한 번 읽을 때 생기는 문제이다. 트랜잭션 1이 읽기 작업을 다시 한 번 반복할 경우 이전에 없던 데이터가 나타나는 현상을 유령 데이터 읽기라고 한다.
격리수준
앞서 설명한 세가지 문제를 해결하려면 락을 사용하는 것이 옳지만, DBMS는 트랜잭션을 동시에 실행시키면서 락보다 좀 더 완화된 방법으로 문제를 해결하는 명령어를 제공한다.
격리 수준은 크게 아래와 같이 4가지로 나뉜다.
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
고립수준/문제 | 오손 읽기 | 반복 불가능 읽기 | 유령데이터 읽기 |
---|---|---|---|
READ UNCOMMITTED | 가능 | 가능 | 가능 |
READ COMMITTED | 불가능 | 가능 | 가능 |
REPEATABLE READ | 불가능 | 불가능 | 가능 |
SERIALIZABLE | 불가능 | 불가능 | 불가능 |
명령어 하나씩 어떤 기능을 하는지 살펴보도록 하자.
READ UNCOMMITTED
READ UNCOMMITTED는 고립 수준이 가장 낮은 명령어로, 자신의 데이터에 아무런 공유락을 걸지 않는다. 또한 다른 트랜잭션에 공유락과 배타락이 걸린 데이터를 대기하지 않고 읽는다. 심지어 다른 트랜잭션이 COMMIT하지 않은 데이터도 읽을 수 있기 때문에 오손 페이지의 데이터를 읽게 된다. 이 명령어는 SELECT 질의의 대상이 되는 테이블에 대해서 락을 설정하지 않은 것과 같다.
tip
공유락 : 공유 Lock은 데이터를 읽을 때 사용되어지는 Lock이다. 이런 공유 Lock은 공유 Lock 끼리는 동시에 접근이 가능하다. 즉, 하나의 데이터를 읽는 것은 여러 사용자가 동시에 할 수 있다라는 것이다. 하지만 공유 Lock이 설정된 데이터에 베타 Lock을 사용할 수는 없다.
베타락 : 베타 Lock은 데이터를 변경하고자 할 때 사용되며, 트랜잭션이 완료될 때까지 유지된다. 베타락은 Lock이 해제될 때까지 다른 트랜잭션(읽기 포함)은 해당 리소스에 접근할 수 없다. 또한 해당 Lock은 다른 트랜잭션이 수행되고 있는 데이터에 대해서는 접근하여 함께 Lock을 설정할 수 없다.
READ COMMITTED
READ COMMITTED는 자신의 데이터를 읽는 동안 공유 락을 걸지만 트랜잭션이 끝나기 전에라도 해지가 가능하다.
REPEATABLE READ
REPEATABLE READ는 자신의 데이터에 설정된 공유락과 베타락을 트랜잭션이 종료할 때 까지 유지하여 다른 트랜잭션이 자신의 데이터를 갱신할 수 없도록 한다. 다른 트랜잭션 데이터는 락 호환성 규칙에 따라 진행한다. 다른 고립화 수준에 비해 데이터의 동시성이 낮아 특별한 상황이 아니라면 사용하지 않는 것이 좋다.
SERIALIZABLE
고립 수준이 가장 높은 명령어로, 실행 중인 트랜잭션은 다른 트랜잭션으로 부터 완벽하게 분리된다. 이 명령어는 네가지 고립화 수준 중 제한이 가장 심하고 데이터의 동시성도 가장 낮다.
나올 수 있는 면접 질문
- 트랜잭션 격리 수준이란 무엇인가요?
- 트랜잭션을 동시에 실행할 때 생길 수 있는 문제에는 무엇이 있나요?
- 트랜잭션 격리 수준 명령어 아시는 게 있을까요?
참고 url
기여자
Kyun Heo
📦