MySQL 기준으로 트랜잭션 격리 수준은 4단계가 있다. 격리 수준이 높은 순으로 정리.
1. SERIALIZABLE
가장 높은 격리 수준이다. 한 트랜잭션 내에서 언제든 반복해서 조회하더라도 동일한 결과가 나오는 repeatable read 가 보장된다.
트랜잭션이 실행되면서 실제 레코드에 바로 반영이 되지만서도, 언두로그에 트랜잭션 시작 전 레코드가 기록된다. 다른 트랜잭션에서는 백업된 언두로그를 읽는다.
단점은 단순한 Select 쿼리에서도 Shared Lock을 걸기 때문에 한번에 한 트랜잭션만 처리할 수 있어 한번에 많은 트랜잭션을 처리하지 못해 처리시간이 오래 걸릴 수 있습니다.
2. Repeatable Read
두번째로 높은 격리 수준이다. MySQL에서 기본으로 세팅된 격리 수준이다. 성능 효율과 높은 수준의 격리성이 보장되기 때문이다.
락을 걸지 않는 트랜잭션들에는 MVCC 를 통해 팬텀리드가 발생하지 않는다. 팬텀 리드란 반복해서 조회했을 때 조회 결과가 다른 현상이다. 이렇게 발생하는 이유는 백업된 언두로그가 아닌 다른 트랜잭션에 의해 레코드가 업데이트된 결과를 조회하기 때문이다.
MVCC(Mutli-Version Concurrency Control) 다중버전 동시성 제어를 통해 동시에 트랜잭션이 처리됨으로 어느정도 처리속도를 가질 수 있다. Insert, Update 를 실제 레코드에 바로 반영하면서도 Repeatable Read 는 보장하기 때문이다. 트랜잭션이 실행되면 트랜잭션 ID 이전 데이터를 기준의 언두로그를 바로 보게 된다. 다른 트랜잭션이 실제 레코드에 데이터를 추가하거나 업데이트하더라도 자신의 트랜잭션 ID 보다 뒤에 발생한 변경사항은 무시한다. 하지만 Select For Update로 하면 언두로그엔 Lock 을 걸 수 없기 때문에 실제 레코드를 조회한다.
그리고 Gap Lock 이 있어 Select For Update로 조회하여 Lock을 걸면 타 트랜잭션에 의한 Insert 는 대기하게 된다. 팬텀리드를 막을 수 있다.
하나의 예외사항은 일반 Select 를 하고 타 트랜잭션에서 Insert 를 하면 바로 레코드에 반영되고 Select For Update 를 해버리면 Insert 된 레코드를 읽어오면서 Repeatable read 가 보장되지 않는다. 이런 경우는 거의 없다.
결론적으로 말하면 거의 Repeatable Read 를 보장한다.
3. Commited Read
타트랜잭션의 커밋된 변경사항까지 조회한다. 트랜잭션 중간에 커밋된 타트랜잭션이 있고 다시 조회했을 때 새로운 결과가 조회된다. 반복조회가 보장되지 않을뿐더러 팬텀리드가 발생할 가능성이 있다. 위험한 격리 수준이다.
4. UnCommited Read
타트랜잭션의 커밋되지 않은 변경사항을 조회한다. 격리 수준이 없다고 볼 수 있다. 언두로그를 조회하지 않고 타 트랜잭션에 의해 실시간 업데이트되는 내용을 바로 조회하기 때문이다.
Dirty Read | Non-Reapeatable Read | Phantom Read | |
Serializable | X | X | X |
Reaptable Read | X | X | O(MySQL은 거의 발생 안함) |
Read Commited | X | O | O |
Read Uncommited | O | O | O |
'공부노트 > 데이터베이스' 카테고리의 다른 글
데이터베이스 Lock (0) | 2023.08.25 |
---|---|
ACID 원칙 (0) | 2023.08.21 |
[MySQL] InnoDB 아키텍처 (0) | 2022.12.11 |
MySQL 메모 (0) | 2022.12.05 |
MYSQL 엔진 아키텍처 (0) | 2022.11.26 |