트랜잭션 격리 수준은 해당 트랜잭션이 데이터베이스 시스템의 다른 트랜잭션에 의해 수행된 데이터 수정과 격리되어야 하는 정도를 정의합니다. 트랜잭션 격리 수준은 아래의 읽기 현상을 기준으로 정의됩니다.
ANSI/ISO 표준 SQL 92에서 제시한 내용으로 트랜잭션 1이 트랜잭션 2가 변경했을 수 있는 데이터를 읽을 때 발생할 수 있는 세 가지 다른 읽기 현상을 의미합니다.
dirty read는 트랜잭션이 실행 중인 다른 트랜잭션에 의해 수정되었지만 아직 커밋되지 않은 행에서 데이터를 읽을 수 있을 때 발생합니다.
dirty read는 Non-repeatable read와 유사하게 작동합니다만, 첫 번째 쿼리가 다른 결과를 반환하기 위해 두 번째 트랜잭션을 커밋할 필요는 없습다는 점에서 차이가 있습니다.
예시에서 트랜잭션 2는 행을 변경하지만 변경 사항을 커밋하지 않았습니다. 그런 다음 트랜잭션 1은 커밋되지 않은 데이터를 읽었고, 트랜잭션 2가 변경 사항을 롤백하거나(트랜잭션 1에서 이미 읽음) 데이터베이스에 대한 다른 변경 사항을 업데이트하면 트랜잭션 1은 존재하지 않는 잘못된 데이터를 읽은게 되어버립니다.
Non-repeatable read는 동일 트랜잭션에서 해당 행이 두번 검색되었지만, 검색된 두 결과가 다른 경우를 의미합니다.
예시에서 트랜잭션 2는 성공적으로 커밋되며, 트랜잭션 1에서 조회될 age 값이 21이 되었지만 트랜잭션 1은 이미 앞선 쿼리에서 age = 20를 검색했었습니다. Non-repeatable read를 보장하기 위해선 두번째 쿼리에서도 age = 20을 반환해야합니다.
phantom read는 range locks이 적용되지 않는 상태에서 범위 조회를 반복할 경우 발생할 수 있는 Non-repeatable read의 특별한 경우입니다.
Phantom read는 트랜잭션 과정에서 다른 트랜잭션이 읽고 있는 레코드에 새 행을 추가하거나 제거할 때 발생합니다.
위와 같은 읽기 현상을 기반으로 4가지 격리 수준이 정의되었습니다. Read uncommitted, Read committed, Repeatable read, Serializable 순으로 좀 더 높은 격리 수준을 제공합니다.
격리 수준이 높을 수록 고립성(안정성)을 제공하며, 대신 시스템의 잠금 오버헤드로 인한 성능 문제와, 교착 상태 발생 가능성이, 동시성이 높아집니다.
가장 낮은 격리 수준으로 한 트랜잭션은 다른 트랜잭션이 수행한 아직 커밋되지 않은 변경 사항을 읽을 수 있습니다. Dirty read, Non-repeatable read, Phantom read 현상 모두 재현 가능하며, 이 수준에서 트랜잭션은 서로 격리되지 않습니다.
읽은 모든 데이터가 커밋되어 있음을 보장하는 격리 수준입니다. 커밋된 데이터만을 조회하므로 Dirty read가 재현되지 않습니다. 대신 Non-repeatable read, Phantom read 현상은 재현될 수 있습니다.
반복 읽기를 보장하는 격리 수준입니다. 커밋된 데이터만을 조회하므로 Dirty read가 재현되지 않고, Non-repeatable read가 재현되지 않습니다. 대신 Phantom read 현상은 재현될 수 있습니다.
가장 높은 격리 수준으로 동시에 실행되는 트랜잭션이 직렬로 실행되는 것처럼 동작함을 보장합니다. Dirty read, Non-repeatable read, Phantom read 현상 모두 재현되지 않습니다.
각 DBMS에 따라 기본으로 제공하는 격리 수준은 달라질 수 있습니다. 예시로 Oracle은 READ COMMITTED를, MySQL은 REPEATABLE READ를 기본 격리 수준으로 제공합니다.
또한 위의 각각의 격리 수준에 대한 구현 방법은 DBMS에 따라 달라질 수 있습니다.
출처