1. 개요
- 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지 나타내는 것
- 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것
2. 격리성 관련 동시성 이슈
가정) 한 트랜잭션 = t1, 다른 트랜잭션 = t2
1. Dirty Read
- t1이 데이터에 접근하여 값을 'A'에서 'B'로 변경 후 아직 커밋하지 않은 상태에서, t2가 해당 데이터를 read하면 'B'를 읽게 됨.
- 이 때 t1이 최종 커밋을 하지 않고 종료되면, t2가 가진 데이터가 꼬이게 됨.
2. Non-Repeatable Read
- t1이 데이터를 Read할 때, t2가 데이터에 접근하여 값을 변경하거나 데이터를 삭제 후 커밋함.
- 이후 t1이 해당 데이터를 다시 read하려고 하면 변경 또는 삭제된 데이터를 조회하게 됨.
3. Phantom Read
- t1 중에 특정 조건으로 데이터를 검색하여 결과를 얻음.
- 이때 t2이 접근하여 해당 조건의 데이터 일부를 삭제/추가하면, 종료되지 않은 t1이 다시 해당 조건으로 데이터를 조회할 경우 t2에서 추가/삭제된 데이터가 함께 조회/누락 됨.
- 이후 t2가 롤백을 하면 데이터가 꼬이게 됨.
3. 격리수준
격리성 관련 문제점들을 해결하기 위해 ANSI 표준에서 트랜잭션의 격리성과 동시 처리 성능 사이의 Trade-off를 두고 4단계 격리수준을 나눔.
✅ LV.0 : READ UNCOMMITTED
한 트랜잭션의 변경된 내용을 COMMIT이나 ROLLBACK과 상관 없이 다른 트랜잭션에서 읽을 수 있는 격리수준
- 장점
- 데이터베이스나 페이지, 열 등에 잠금을 유지하는 데 드는 간접 비용이 제일 적음
- 교착 상태에 빠질 위험이 적어 성능이 빠르고 우수함
- 주의
- 더티 리드(Dirty Read) 발생 가능성 존재
- 데이터 정합성에 문제가 많으므로, 되도록이면 사용하지 않는 것이 이상적
- 다음과 같은 경우에만 사용하는 것을 권장
- 갱신되지 않을 과거 자료를 열람할 때
ex) 실험실에서 전달 된 환자의 시험 결과
- 몇몇 행이 제대로 조회되지 않아도 무관할 만큼 거대한 양의 데이터를 어림잡아 집계할 때
- 트랜잭션 도중에 값을 얻어낼 수 있으므로, 복잡한 stored procedure나 함수가 포함된 디버깅을 할 때 중간 과정을 확인하기 위해 사용하는 경우도 존재
✅ LV.1 : READ COMMITTED
COMMIT이 완료된 데이터만 조회 가능한 격리수준
- 특징
- 다른 트랜잭션에서의 변경 사항이 커밋되지 않은 경우, 실제 테이블의 값이 아닌 Undo 영역에 백업된 레코드에서 값을 가져옴
- 커밋된 결과만 읽어오므로 Dirty Read가 발생하지 않음
- RDB(관계형 데이터베이스)에서 대부분 기본적으로 사용되는 격리수준
- 주의
- Non-repeatable Read 발생 가능성 존재
- 잠금이 발생하므로 속도나 성능에 있어서 느릴 수 있음
- 트랜잭션 간 고립성을 완전히 보장하지 못함
→ 각 트랜잭션의 정확도를 생명으로 하는 웹 애플리케이션 구동에는 적합하지 않음
ex) 은행 계좌 정보 조회
✅ LV.2 : REPEATABLE READ
트랜잭션이 시작되기 전에 커밋된 내용에 관해서만 조회할 수 있는 격리수준
- 특징
- MySQL DBMS에서 기본으로 사용
- 자신의 트랜잭션 번호보다 낮은(먼저 일어난) 트랜잭션 번호에서 변경(커밋)된 것만 보게 됨
- 모든 InnoDB의 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가짐
- Undo 영역에 백업된 모든 레코드는 변경을 발생시킨 트랜잭션의 번호를 포함함
- Undo 공간에 백업해두고 실제 레코드 값 변경
- 백업된 데이터는 불필요하다고 판단되는 시점에 주기적으로 삭제됨
- 트랜잭션이 범위 내에서 조회한 데이터 내용이 항상 동일함을 보장
- 이미 존재하는 레코드에 대해서만 보장
- 주의
- 다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대한 수정이 불가능함
- 잠금이 적용되는 범위가 넓어져 성능과 속도가 느려짐
- Phantom Read 발생 가능성 존재
→ MySQL의 InnoDB는 멀티 버전 동시성 제어를 통해 어느정도 극복(next key lock 이용)
✅ LV.3 : SERIALIZABLE
한 트랜잭션을 다른 트랜잭션으로부터 완전히 분리하는 격리수준
- 가장 단순하면서도 엄격한 격리수준
- INSERT되는 레코드도 고려하여 격리성 유지
- 완벽한 읽기 일관성 모드 제공
- 한 트랜잭션이 특정 테이블을 조회할 경우, 다른 트랜잭션은 해당 테이블의 데이터를 추가/변경/삭제할 수 없음
→ 동시처리 능력이 다른 격리수준보다 떨어지며, 성능저하 발생
- 모든 것이 순차적으로 진행되므로 Phantom Read가 발생하지 않음
- 데이터베이스에서 거의 사용되지 않음
📊 격리수준 별 동시성 문제 비교
Isolation Level | Dirty Read | Non-repeatable Read | Phantom Read |
---|
READ UNCOMMITTED | O | O | O |
READ COMMITTED | X | O | O |
REPEATABLE READ | X | X | O |
SERIALIZABLE | X | X | X |
📖 참고