데이터베이스는 일관성을 유지하기 위해 ACID를 따릅니다. 이 네가지 속성( 원자성, 일관성, 독립성, 지속성 ) 중에 독립성(Isolation)은 서로 다른 트랜잭션이 데이터 수정 등으로 서로에게 문제가 발생하지 않도록 서로 격리하는것을 독립성(Isolation), 즉 트랜잭션 격리수준이라고 합니다.
데이터베이스에서 트랜잭션은 작업 단위를 나타내며 성공시 커밋(Commit), 실패시 롤백(Rollback)을 하여 데이터를 정확하게 관리할 수 있는 기능입니다.
ACID는 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 내용을 가리키는 약어입니다. 짐 그레이가 1970년 말에 정의하였습니다.
원자성(Atomicity)은 트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력이다. 예를 들어, 자금 이체는 성공할 수도 실패할 수도 있지만 보내는 쪽에서 돈을 빼 오는 작업만 성공하고 받는 쪽에 돈을 넣는 작업을 실패해서는 안된다. 원자성은 이와 같이 중간 단계까지 실행되고 실패하는 일이 없도록 하는 것이다.
일관성(Consistency)은 트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지하는 것을 의미한다. 무결성 제약이 모든 계좌는 잔고가 있어야 한다면 이를 위반하는 트랜잭션은 중단된다.
독립성(Isolation)은 트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다. 이것은 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미한다. 은행 관리자는 이체 작업을 하는 도중에 쿼리를 실행하더라도 특정 계좌간 이체하는 양 쪽을 볼 수 없다. 공식적으로 고립성은 트랜잭션 실행내역은 연속적이어야 함을 의미한다. 성능관련 이유로 인해 이 특성은 가장 유연성 있는 제약 조건이다. 자세한 내용은 관련 문서를 참조해야 한다.
지속성(Durability)은 성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다. 시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 함을 의미한다. 전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다. 트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.
위 내용은 위키백과에서 ACID를 설명해 놓은 글 입니다. 원자성, 일관성, 독립성, 지속성은 어찌보면 데이터베이스에서 당연히 필요한 기능이라고 볼 수 있습니다.
이 중 독립성(Isolation), 즉 격리수준을 알아보겠습니다.
* dirty read : 아직 커밋되지 않은 수정 중인 데이터를 다른 트랜잭션에서 읽을 수 있도록 허용할 때 발생합니다.
* Non-Repeatable Read : 한 트랜잭션 내에서 같은 쿼리를 두번 조회할 때, 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제함으로써 두 쿼리가 다르게 나타나는 것을 말합니다.
* Phantom Read : 한 트랜잭션 안에서 일정범위의 레코드를 두번 이상 읽을 때, 첫 번재 쿼리에서 없던 유령 레코드가 두번째 쿼리에서 나타나는 현상을 말합니다.
위와같이 트랜잭션 격리수준은 네 단계로 나눠져 있습니다.
아래 과정에서 mysql 쿼리로 실습하면서 설명하겠습니다.
간단하게 id, name, age 컬럼이 있는 USER 테이블을 생성했습니다.
임시로 데이터를 넣어줬습니다.
아직 커밋되지 않은 다른 트랜잭션의 변경사항을 읽을 수 있습니다.
Dirty Read, Non-Repeatable Read, Phantom Read 현상 발생
왼쪽 : T1, 오른쪽 : T2
결과 : 값을 변경한 T1의 commit이 이루어지지 않았음에도 불구하고 T2에서 조회시 변경 값으로 나타납니다. 즉 아직 커밋되지 않은 다른 트랜잭션의 변경사항을 읽을 수 있습니다. 이를 dirty read라고 합니다.
( 가장 낮은 격리 수준 )
커밋이 되어있는 데이터만을 읽어옵니다.
Non-Repeatable Read, Phantom Read 현상 발생
왼쪽 : T1, 오른쪽 : T2
결과 : T1의 트랜잭션 commit이 이루어지지 않았기 때문에 T2에서는 변경 전 값이 나옵니다. 따라서 dirty read를 허용하지 않습니다.
다른 트랜잭션이 커밋을 해도 변경 데이터를 읽지 않습니다. ( 완전 격리 )
Phantom Read 현상 발생
왼쪽 : T1, 오른쪽 : T2
결과 : T1의 트랜젝션 commit이 이루어져도 값이 달라지지 않습니다. 따라서 완전히 격리되었다고 볼 수 있습니다.
가장 높은 수준의 격리 수준입니다. REPEATABLE READ 와 유사하지만 Phantom Read를 방지합니다. 범위 잠금 기능을 사용하여 테이블에 인덱스가 있으면 WHERE절에 사용된 인덱스 범위(예: ID 1 ~ 3 사이)에 따라 레코드를 잠급니다. 테이블에 인덱스가 없으면 전체 테이블을 잠급니다.
참고 링크
https://www.geeksforgeeks.org/transaction-isolation-levels-dbms/
http://wiki.gurubee.net/pages/viewpage.action?pageId=21200923