List
Search
Preface
•
트랜잭션의 격리 수준이란?
◦
여러 트랜잭션이 동시에 실행될 때, 한 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터에 접근할 수 있는지를 결정하는 것
◦
격리 수준이 높아질수록 트랜잭션 간의 데이터 격리 정도가 높아지나, 일반적으로 동시 처리 성능은 낮아짐
•
격리 수준 종류
◦
READ UNCOMMITTED
◦
READ COMMITTED
◦
REPEATABLE READ
◦
SERIALIZABLE
•
격리 수준과 3가지 부정합
DIRTY READ | NON-REPEATABLE READ | PHANTOM READ | |
READ UNCOMMITTED | O | O | O |
READ COMMITTED | X | O | O |
REPEATABLE READ | X | X | O (InnoDB는 X) |
SERIALIZABLE | X | X | X |
•
1. READ UNCOMMITTED
1.1. 개요
•
가장 낮은 수준의 격리 수준
•
Dirty Read 발생
◦
트랜잭션에서 변경한 내용이 커밋 여부와 관계없이 다른 트랜잭션에서 즉시 조회 가능
◦
한 트랜잭션에서 수정한 데이터가 다른 트랜잭션에서 볼 수 있음
◦
예시)
▪
트랜잭션 A가 데이터를 수정하고 커밋하지 않은 상태에서 트랜잭션 B가 해당 데이터를 읽음
▪
트랜잭션 A가 롤백하더라도 트랜잭션 B는 수정된 데이터를 이미 본 상태가 됨
1.2. 문제점
•
데이터의 일관성이 보장되지 않음
•
정합성에 문제가 많음
•
이러한 이유로 READ UNCOMMITTED는 실제로 거의 사용되지 않음
2. READ COMMITTED
2.1. 개요
•
오라클 DBMS에서 기본으로 사용되는 격리 수준이며, 온라인 서비스 환경에서 널리 사용됨
•
커밋된 데이터만 다른 트랜잭션에서 조회 가능
◦
한 트랜잭션이 데이터를 수정하더라도 해당 트랜잭션이 커밋되기 전까지 다른 트랜잭션에서 수정된 내용을 볼 수 없음
◦
따라서 더티 리드 현상은 발생하지 않음
•
예시)
2.2. 문제점
•
NON-REPEATABLE READ 문제가 발생
•
즉, 한 트랜잭션 내에서 같은 SELECT 쿼리를 두 번 실행했을 때 결과가 달라질 수 있음
•
트랜잭션이 진행되는 동안 다른 트랜잭션에서 데이터를 수정하고 커밋할 수 있기 때문
•
예시)
3. REPEATABLE READ
3.1. 개요
•
MySQL의 InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준
•
MVCC (Multi-Version Concurrency Control)
◦
트랜잭션이 시작된 후, 해당 트랜잭션이 완료될 때까지 같은 SELECT 쿼리는 항상 동일한 결과를 반환
◦
MVCC를 사용하여 트랜잭션이 시작될 때의 데이터 상태를 유지
◦
트랜잭션이 변경을 수행하기 전에 데이터를 언두(Undo) 영역에 백업(롤백될 가능성을 대비하여)해두고, SELECT 쿼리는 언두 영역의 데이터를 참조하여 일관된 결과를 제공
•
트랜잭션과 언두 영역
◦
모든 InnoDB 트랜잭션은 고유한 트랜잭션 번호 (Auto Incremented) 값을 가짐
◦
언두 영역에 백업된 모든 레코드는 변경을 발생시킨 트랜잭션 번호를 가짐
◦
언두 영역에 백업된 데이터는 InnoDB 스토리지 엔진이 불필요하다고 판단되는 시점에 주기적으로 삭제
◦
REPEATABLE READ 격리수준에서는 MVCC 보장을 위해 실행중인 트랜잭션 가운데 가장 오래된 트랜잭션 번호보다 앞선 언두 영역의 데이터는 삭제할 수 없음
•
예시)
3.2. 문제점
•
처리 성능 저하
◦
언두 로그 영역에 백업된 레코드가 많아지면 MySQL 서버의 처리 성능 저하가 발생할 수 있음
•
PHANTOM READ 현상이 발생할 수 있음
◦
트랜잭션 내에서 특정 조건을 만족하는 레코드가 보였다가 사라지거나, 새로운 레코드가 보이는 현상
◦
MySQL의 InnoDB에서는 갭 락과 넥스트 키 락을 통해 이러한 문제를 완화 가능
•
PHANTOM READ 예시)
◦
SELECT 쿼리 결과가 달라질 수 있음
◦
SELECT → INSERT → SELECT FOR UPDATE
4. SERIALIZABLE
4.1. 개요
•
가장 단순하면서 가장 높은 수준의 격리 수준
•
모든 트랜잭션이 직렬화된 것처럼 동작하도록 보장
•
다른 격리수준은 순수한 SELECT 작업은 아무런 레코드 잠금도 설정하지 않고 실행되나, 이 격리수준에서는 데이터를 읽을 때도 공유 잠금(읽기 잠금)을 획득하고, 다른 트랜잭션은 해당 레코드를 수정할 수 없음
◦
MVCC 사용 X. S Lock, X Lock 사용
◦
따라서 PHANTOM READ가 발생하지 않음
4.2. 문제점
•
모든 트랜잭션이 순차적으로 처리되어야 하므로 동시성 성능이 크게 떨어짐
•
동시 처리 성능이 낮아지기 때문에 실시간 트랜잭션이 많은 환경에서는 잘 사용되지 않음
•
MySQL의 InnoDB에서는 이미 REPEATABLE READ 수준에서 PHANTOM READ 문제가 해결되므로 SERIALIZABLE을 사용해야 하는 경우는 거의 없음