Transaction isolation level 에 따라 일어 날 수 있는 현상
Drity read
커밋되지 않거나 아직 dirty buffer에 있는 데이터를 읽을 수 있는것을 말한다. 예를 들어 변경 후 아직 커밋되지 않은 값을 읽는데 변경을 가한 트랜잭션이 최종적으로 롤백된다면 그 값을 읽은 트랜잭션은 일관성이 없는 상태가 된다.
Non repeateble read
한 트랜잭션 내에서 같은 쿼리를 두번 수행했는데 그 사이에 다른 세션에서 수정 또는 삭제가 일어나 두 쿼리의 결과값이 다르게 나타나는것을 말한다.
Phantom Read
한 트랜잭션 내에서 같은 쿼리를 두 번 수행할때, 다른 트랜잭션에서 삽입이 일어나면 두 쿼리의 결과값이 다르게 나타나는 현상을 말한다. Nonrepeatable read와의 차이점은 데이터가 변경되지는 않았지만 이전보다 쿼리에 만족하는 데이터값이 늘어난다는 점이 차이가 있다. ( 행값의 변화가 있느냐, 행의 총 수의 변화가 있느냐의 차이)
Serializtion Anomaly
일련의 트랜잭션 단위를 수행한 결과가 순서대로 수행했을 시 확인되는 트랜잭션들의 결과와 상이한 현상.
Transaction 격리 level
READ UNCOMMITTED
select for update, delete 구문 실행 후, commit, rollback에 관계 없이 수행전의 데이터를 읽어 들인다. 이로 인해 데이터 간의 일관성을 보장하기 위한 lock이 발생하지 않는다.
트랜잭션에서 처리 중인 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용한다. 해당 수준에서는 Dirty Read, Non-Repeatable Read, Phantom Read가 일어날 수 있다. 이 설정은 정합성에 문제가 있기 때문에 권장하는 설정은 아니다.
기존 RDBMS 에서는 위의 방식으로 인해 일관성이 보장되지 않는 데이터를 읽어 들이는 Dirty Read 가 발생할 수 있으나 PostgreSQL는 이를 허용하지 않는다.
DB 내에서 SET 으로 옵션을 설정 할 수 있으나 PostgreSQL 에서 작동 메커니즘은 READ COMMITTED와 거의 동일하다. 그래서 공식 DOC 에서도 실제 Isolation 유형은 READ UNCOMMITED/READ COMMITTED를 묶어서 아래의 2개와 함께 총 3개로 구분한다.
READ COMMITED
ORACLE, PostgreSQL의 default Isolation Level 이다.
Read uncommitted 와는 다르게 select for update, delete 구문 실행 후, commit 된 데이터를 읽어 들인다.
트랜잭션이 커밋되어 확정된 데이터만 다른 트랜잭션이 읽도록 허용한다. 따라서 Dirty Read의 발생가능성을 막는다. 커밋 되지 않은 데이터에 대해서는 실제 DB 데이터가 아닌 Undo 로그에 있는 이전 데이터를 가져오는 것. 하지만 Non-Repeatable Read와 Phanton Read에 대해서는 발생 가능성이 있다.
PostgreSQL에서는 데이터 변경이 발생 시, commit되지 않은 데이터 변경 내역 마다 새로운 페이지를 만들어서(ORACLE에서 데이터블록) 변경이력을 관리하는 MVCC 개념을 사용하기 때문에 commit 되지 않는 내용들에 대해서는 기존에 있는 갱신 이전 버전의 페이지를 확인한다.
위의 방식으로 인해 비슷한 시간대에 동일 쿼리를 수행했는데 처음 수행했을떄 보여지는 데이터 row와 다른 트랜잭션에서 commit 이후에 보여지는 row 정합성 차이 혹은 조회 일관성 이상등이 발생 할 수 있다.
이로 인하여 이상이 발생하는 row를 phantom row라고 하며 (read 이상은 phantom read라고 한다), 이를 방지하기 위해서 gap lock 이라는 개념이 존재하는데 해당 격리 단계 에서는 사용하지 않는다.
REPEATABLE READ
Mysql/MariaDB의 default Isolation Level 이다.
동일 세션내의 트랜잭션에서도 데이터 조회 변동 시점간의 gap을 관리하기 위하여 snapshot 이라는 개념을 사용하며, 이를 통하여 다른 세션으로 인하여 데이터가 변동되도 각 시점간의 snapshot을 이용하여 일관된 데이터를 조회 및 변동할 수 있다.
위의 방식으로 인하여 gap lock을 사용하므로 이 lock이 발생 할 수 있으며 select for update, delete 구문 실행 후, commit, rollback 및 다양한 상황에서 조건에 따라 record lock 도 발생 가능하다.
조건에 따라 index range scan lock 도 발생하기 때문에 다른 세션으로 부터 들어오는 create select, insert select 방식의 조건 데이터 조회 후 기입 방식도 lock이 걸릴 수 있다.
트랜잭션내에서 삭제, 변경에 대해서 Undo 로그에 넣어두고 앞서 발생한 트랜잭션에 대해서는 실제 데이터가 아닌 Undo 로그에 있는 백업데이터를 읽게 한다. 이렇게 함으로써 트랜잭션 중 값의 변경에 대해서 일정한 값으로 처리할 수 있습니다. 이렇게하면 삭제와 수정에 대해서 트랜잭션내에서 불일치를 가져오던 Non-Reapeatable Read를 해소할 수 있다.
SERIALIZABLE(직렬화)
격리성이 제일 높은 단계다.
트랜잭션 내에서 쿼리를 두 번 이상 수행할 때, 첫 번째 쿼리에 있던 레코드가 사라지거나 값이 바뀌지 않음은 물론 새로운 레코드가 나타나지도 않도록 하는 설정이다.
작동구조는 REPEATABLE READ와 유사하지만 아래에 설명될 일련의 트랜잭션 기입 및 조회가 동시에 이뤄질 시 발생할 수 있는 Serialization Anomaly를 방지하기 위하여 동시적으로 데이터 변동으로 인한 상이성이 보이면 아래의 에러를 발생시킨다.
ERROR: could not serialize access due to concurrent update
오라클은 Read committed와 Serializable을 지원하고 SQL server 와 DB2, PostgreSQL는 4가지 레벨을 모두 지원한다. (오라클은 select ... for update 구문을 통해 Repeatable Read를 구현할 수는 있지만 공식적으로 트랜잭션 고립성 레벨에서 지원하는 것은 두가지 뿐)
Isolation Level | Dirty Read | Nonrepeatable Read | Phantom Read | Serialization Anomaly |
Read uncommitted | 허용 | 가능 | 가능 | 가능 |
Read committed | 불가능 | 가능 | 가능 | 가능 |
Repeatable read | 불가능 | 불가능 | 허용 | 가능 |
Serializable | 불가능 | 불가능 | 불가능 | 불가능 |
'Oracle > Admin' 카테고리의 다른 글
[Oracle] Index 사이즈 예측 (0) | 2024.02.14 |
---|---|
[Oracle] SQL PLAN 고정 방법 2가지 (0) | 2024.02.07 |
[Oracle] Dynamic Statistics (0) | 2023.12.07 |
[Oracle] 패치 (2) | 2023.11.09 |
[Oracle] TEMPORARY TABLE (0) | 2023.10.13 |