Monthly archives of “July 2012

comment 1

데이터베이스 Isolation Level

Isolation Level 의 필요성

데이터베이스의 무엇보도 중요한 기능은 데이터를 정확하고 안전하게 저장하며 데이터의 변경이나 수정시 제한을 두어 안정성을 저해하는 요소를 막아 데이터 상태들을 항상 옳게 유지하는 것을 의미한다. 즉, 흔히 말하는 무결성을 보장하는 것이다.

데이터의 무결성 보장과 관련된 트랜잭션의 ACID 보장이라고 할 수 있다.

ACID는 Atomicity, Consistency, Isolation, Durability의 약자인데 트랜잭션 보장을 위해 갖추어야 할 속성들을 나타낸다. 이를 위해서는 DB는 ACID가 의미하는 바와 같이 트랜잭션이 원자적이면서도 독립적인 수행을 하도록해야 한다. 그래서 등장하는 개념이 Locking 이다.

Locking 은 트랜잭션이 DB를 다루는 동안 다른 트랜잭션이 관여하지 못하게 막는 것이다. 하지만 단순하게 무조건적인 Locking으로 동시에 수행되는 많은 트랜잭션들을 일렬로 죽 세워서 순서대로 처리하는 방식으로 구현된다면 DB의 성능은 현저하게 떨어지게 된다. 반대로 응답성을 높이기 위해 Locking 범위를 줄인다면 잘못된 값이 처리 될 여지가 있다. 그래서 최대한 효율적인 Locking 방법이 필요하다.

이와 관련된 Locking 방법이 Isolation Level이라고 생각하면 된다.

Isolation Level 의 종류

  1. Read Uncommitted

    • SELECT 문장을 수행하는 경우 해당 데이터에 Shared Lock이 걸리지 않는 Level입니다. 따라서, 어떤 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 B라는 아직 완료되지 않은(Uncommitted 혹은 Dirty) 데이터 B를 읽을 수 있습니다.
  2. Read Committed

    • SQL Server가 Default로 사용하는 Isolation Level입니다. 이 Level에선 SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸립니다. 그러므로, 어떠한 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 해당 데이터에 접근할 수 없습니다.
  3. Repeatable Read

    • 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정이 불가능합니다. 가령, Select col1 from A where col1 between 1 and 10을 수행하였고 이 범위에 해당하는 데이터가 2건이 있는 경우(col1=1과 5) 다른 사용자가 col1이 1이나 5인 Row에 대한 UPDATE이 불가능합니다. 하지만, col1이 1과 5를 제외한 나머지 이 범위에 해당하는 Row를 INSERT하는 것이 가능합니다.
  4. Serializable

    • 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능합니다. 예를 들어, Repeatable Read의 경우 1에서 10 사이에 해당되는 데이터에 대한 UPADTE이 가능하였습니다. 하지만 이 Level에서는 UPDATE 작업도 허용하지 않습니다.

출처 : http://support.microsoft.com/kb/601430/ko

위의 Transaction Isolation Level 은 Read Uncommited 에서 Serializable  순으로 Concurrency 는 높아지고 속도는 높아진다. 따라서 이 둘의 균형을 잘 맞추는 것이 중요하다.

위 네가지 Isolation Level  에 따라 나타나는 현상이 세가지가 있다.

  • Dirty Read
  • Repeatable Read
  • Phantom Read

각각의 의미는 다음과 같다.

  • Dirty Read

    • 어떤 트랜잭션에서 아직 실행이 끝난지 않은 다른 트랜잭션에 의한 변경 사항을 보게 되는 되는 경우를 dirty read 라고 한다. 만약 원래 트랜잭션에서 그 변경 사항을 롤백하면 그 데이터를 읽은 트랜잭션은 dirty 데이터를 가지고 있다고 말한다.
  • Repeatable Read

    • 어떤 트랜잭션에서 같은 질의를 사용했을 때 질의를 아무리 여러번 해도 그리고 다른 트랜잭션에서 아무리 여러 번 그 행을 변경해도 항상 같은 데이터만 읽어드리는 경우를 repeatable read 라고 한다. 즉 repeatable read 가 요구되는 트랜잭션에서는 다른 트랜잭션에 의한 변경 사항을 볼 수가 없다. 그러한 변경 사항을 보고 싶으면 어플리케이션에서 트랜잭션을 새로 시작해야 한다.
  • Phantom read

    • phantom read 는 다른 트랜잭션에 의한 변경 사항으로 인해 현재 사용 중인 트랜잭션의 WHERE 절의 조건에 맞는 새로운 행이 생길 수 있는 경우에 관한 것이다. 예를 들어, 잔고가 $100 미만인 계좌를 모두 찾아내는 트랜잭션에 있고, 이 트랜잭션에서 그 데이터를 두 번 읽는다고 가정하자. 처음 데이터를 읽어들이고 난 후에 다른 트랜잭션에서 잔고가 $0인 계좌를 새로 만들면 이 계좌도 잔고가 $100 이하라는 조건에 맞게 된다. 트랜잭션 격리 수준(Transaction Isolation Level)에서 phantom read 를 지원하면 새로운 “유령(phantom)”행이 나오지만 지원하지 않으면 새로 생긴 행을 볼 수 없다.
Isolation Level Dirty Read Nonrepeatable Read Phantom Read
READ UNCOMMITTED Permitted Permitted Permitted
READ COMMITTED Permitted Permitted
REPEATABLE READ Permitted
SERIALIZABLE

Tabel1. Ansi Isolation Levels

Mysql 의 InnoDB 스토리지 엔진의 기본 Isolation Level이 REPEATABLE-READ 이고 Oracle 은 READ-COMMITED 이다. 각 DBMS별 isolation level 에 자세한 내용은 다음 링크에서 참조할 수 있다.

  • mysql : http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html
  • oracle : http://www.oracle.com/technetwork/issue-archive/2005/05-nov/o65asktom-082389.html

Oracle 은 READ-COMMITED 와 SERIALIZABLE 만 지원하며 나머지 두가지 isolation level  은 지원하지 않는다.