본문 바로가기
Oracle/운영

트랜잭션 격리 수준(isolation level)

by 취미툰 2020. 8. 17.
반응형

제가 관리하는 사이트에서 일어난 이슈였던 격리 수준에 대해서 정리하는 글을 올려보려고 합니다.
ANSI/ISO SQL 표준은 4개 레벨의 트랜잭션 고립성(isolation level)을 정의하고 있습니다. 레벨에 따라 같은 트랜잭션 시나리오로 4개의 다른 결과를 받게 됩니다. 트랜잭션 고립성 수준에 따라 세개의 현상이 발생하게 됩니다. 세개의 현상은 아래에서 설명하겠습니다.

- Dirty read : 커밋되지 않거나 아직 더티버퍼에 있는 데이터를 읽을 수 있는것을 말합니다. 예를들어 변경 후 아직 커밋되지 않은 값을 읽는데 변경을 가한 트랜잭션이 최종적으로 롤백된다면 그 값을 읽은 트랜잭션은 일관성이 없는 상태가 됩니다.


- Non repeatable read : 한 트랜잭션 내에서 같은 쿼리를 두번 수행했는데 그 사이에 수정 또는 삭제가 일어나 두 쿼리의 결과값이 다르게 나타나는 것을 말합니다.


- Phantom Read : 한 트랜잭션 내에서 같은 쿼리를 두번 수행할때, 다른 트랜잭션에서 삽입이 일어나면 두 쿼리의 결과값이 다르게 나타나는 현상을 말합니다. Nonrepeatable read와 차이점은 데이터가 변경되지는 않았지만 이전보다 쿼리에 만족하는 데이터 값이 늘어난다는 점이 차이가 있습니다. (행값의 변화가 있느냐,행의 총 수의 변화가 있느냐의 차이인것 같네요)

ANSI/ISO SQL 표준에서 정의한 트랜잭션 고립성 수준은 아래와 같습니다.


- Read Uncommitted : 트랜잭션에서 처리 중인 커밋되지 않은 데이터를(더티 데이터) 다른 트랜잭션이 읽는것을 허용하는 수준입니다. 세가지다 허용되어 가능한 상태입니다.

- Read Committed : 트랜잭션이 커밋되어 확정된 데이터만 다른 트랜잭션이 읽도록 허용합니다. 오라클의 default 설정입니다. Nonrepeatable read와 Phantom Read는 허용되어 가능한 상태입니다.

- Repeatable Read : 트랜잭션 내에서 쿼리를 두 번 이상 수행할 때, 첫 번째 쿼리에 있던 레코드가 사라지거나 값이 바뀌는 현상을 방지해 줍니다. 하지만 새로운 값이 삽입되는 Phantom read는 허용되어 가능한 상태입니다.

- Serializable Read : 트랜잭션 내에서 쿼리를 두 번이상 수행할 때, 첫 번째 쿼리에 있던 레코드가 사라지거나 값이 바뀌지 않음은 물론 새로운 레코드가 나타나지도 않습니다.

오라클은 Read committed와 Serializable을 지원하고 SQL server 와 DB2는 4가지 레벨을 모두 지원합니다. (오라클은 select ... for update 구문을 통해 Repeatable Read를 구현할 수는 있지만 공식적으로 트랜잭션 고립성 레벨에서 지원하는 것은 두가지 뿐입니다.)

동시성 제어와 데이터의 일관성의 관계는 반비례일 수 밖에 없습니다. 많은 사람들이 사용하기 위해서는 데이터의 고립성 수준을 낮게 설정해야 하며, 그렇게 되면 데이터의 일관성이 깨지는 확률이 높아지기 때문입니다. 반대로 데이터의 일관성을 유지하기 위해서 고립성 수준을 높게 설정했다면, 데이터에 lock이 걸려 많은 사람들이 조회 및 수정을 할 수 없게되고 동시성은 떨어지게 될것입니다.






출처 : https://blogs.oracle.com/oraclemagazine/on-transaction-isolation-levels

반응형

댓글