Isolation Level의 필요성
-
데이터베이스의 무엇보도 중요한 기능은 데이터를 정확하고 안전하게 저장하며
데이터의 변경이나 수정시 제한을 두어 안정성을 저해하는 요소를 막으며
데이터 상태들을 항상 옳게 유지하는 것을 의미한다. -
즉 흔히 말하는 무결성을 보장하는 것이다.
-
데이터의 무결성 보장과 관련된 트랜잭션의 ACID 보장이라고 할 수 있다.
-
ACID(Atomicity, Consistency, Isolation, Durability)는 트랜잭션 보장을 위해 갖추어야 할 속성들을 나타낸다.
-
이를 위해서는 DB는 ACID가 의미하는 바와 같이 트랜잭션이 원자적이면서도 독립적인 수행을 하도록해야 한다.
-
그래서 등장하는 개념이 Locking이다.
-
Locking은 트랜잭션이 DB를 다루는 동안 다른 트랜잭션이 관여하지 못하게 막는 것이다.
-
하지만 무조건적인 Locking으로 동시에 수행되는 많은 트랜잭션들을 일렬로 대기시킨다면
DB의 성능은 현저하게 떨어진다. -
반대로 응답성을 높이기 위해 Locking 범위를 줄인다면 잘못된 값이 처리 될 여지가 있다.
-
그래서 최대한 효율적인 Locking 방법이 필요하다.
-
이와 관련된 Locking 방법이 Isolation Level이라고 생각하면 된다.
Isolation Level의 종류
Read Uncommitted
-
SELECT 문장을 수행하는 경우 해당 데이터에 Shared Lock이 걸리지 않는 Level이다.
-
따라서 어떤 사용자가 A -> B로 데이터를 변경하는 동안
다른 사용자는 B라는 아직 완료되지 않은(Uncommitted 혹은 Dirty) 데이터 B를 읽을 수 있다. -
트랜잭션이 끝나지 않은 상황에서 각기 다른 트랜잭션이 변경한 내용에 대한 조회가 가능하다.
-
데이터베이서의 일관성을 유지할 수 없다.
- Transaction1이 수행 중에 Transaction2가 값을 변경할 경우
Transaction1이 다시 조회를 하는 시점에 Commit은 하지 않았지만
이미 Transaction2가 값을 변경하였기 때문에
아무개 에서 개발자 로 값이 변경되어 조회가 된다.
Read Committed
-
SQL Server가 Default로 사용하는 Isolation Level이다.
-
이 Level에선 SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸린다.
-
그러므로 어떠한 사용자가 A -> B로 데이터를 변경하는 동안
다른 사용자는 해당 데이터에 접근할 수 없다. -
Read Uncommitted와 다르게 Commit이 이루어진 데이터가 조회된다.
-
하지만 어떠한 사용자가 A -> B로 데이터를 변경하는 동안
다른 Transaction은 접근할 수 없어 대기하게 된다.
-
Transaction2가 Update를 하게된다.
-
아직 Commit하지 않아 Transaction1은 SELECT을 하지 못하고 대기하게 된다.
-
Transaction2가 Commit명령어를 날리게 된다.
-
이제 Transaction2는 조회가 가능하다.
Repeatable Read
-
트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리므로
다른 사용자는 그 영역에 해당되는 데이터에 대한 수정이 불가능하다. -
가령 SELECT col1 from A where col1 between 1 and 10 을 수행하였고
이 범위에 해당하는 데이터가 2건이 있는 경우(col1 = 1,5)
다른 사용자가 col1 = 1 or col1 = 5인 Row에 대한 UPDATE 작업이 불가능하다. -
하지만 col1이 1과 5를 제외한 나머지 범위에 해당하는 Row를 INSERT하는 것은 가능하다.
-
Transaction이 범위내에서는 조회한 데이터의 내용이 항상 동일함을 보장한다.
-
Transaction1이 SELECT시점에 아무개가 조회된다.
-
Transaction2가 Update후 Commit을 시행하였지만 Update가 안된다.
그러나 Insert는 된다. -
Transaction1이 다시 조회 해도
Transaction2가 Commit이 되지 않았기 때문에 아무개로 조회된다.
하지만 Insert한 동네개발자는 조회된다. -
Transaction1이 종료되면 다시 Commit이 이루어지기 때문에 개발자로 조회가 된다.
Serializable
-
말 그대로 모든 동작이 직렬화되어 작동한다.
-
Repeatable Read와 다르게 Insert를 하여도 작동하지 않게 된다.
-
트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리므로
다른 사용자는 그 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능하다. -
예를 들어 Repeatable Read의 경우 1에서 10 사이에 해당되는 데이터에 대한 UPADTE이 가능하다.
-
하지만 이 Level에서는 UPDATE 작업도 허용하지 않는다.
부작용(Side Effect)
Dirty Read
-
어떤 트랜잭션에서 아직 실행이 끝난지 않은 다른 트랜잭션에 의한 변경 사항을 보게되는 경우를 Dirty Read라고 한다.
-
만약 수정한 트랜잭션이 그 변경 사항을 롤백하면
그 데이터를 읽은 다른 트랜잭션은 Dirty 데이터를 가지고 있다고 말한다.
Non-Repeatable Read
-
어떤 트랜잭션에서 같은 질의를 사용했을 때 질의를 아무리 여러번 해도
그리고 다른 트랜잭션에서 아무리 여러 번 그 행을 변경해도
항상 같은 데이터만 읽어드리는 경우를 Non-Repeatable Read라고 한다. -
즉 Non-Repeatable Read가 요구되는 트랜잭션에서는 다른 트랜잭션에 의한 변경 사항을 볼 수가 없다.
-
그러한 변경 사항을 보고 싶으면 어플리케이션에서 트랜잭션을 새로 시작해야 한다.
Phantom Read
-
Phantom Read는 다른 트랜잭션에 의한 변경 사항으로 인해
현재 사용 중인 트랜잭션의 WHERE 절의 조건에 맞는 새로운 행이 생길 수 있는 경우에 관한 것이다. -
예를 들어 잔고가 $100 미만인 계좌가 2개인 DB에서
-
$100 미만인 계좌를 찾는 트랜잭션이 있고
-
그 트랜잭션안에서 Select 쿼리를 2번 수행한다고 가정하자.
-
처음에 데이터를 읽으면 2개의 계좌를 찾게 된다.
-
이 때 다른 트랜잭션에서 $0인 계좌를 새로 만들면
-
두번째 데이터를 읽을 땐 3개의 계좌를 찾게 된다.
-
이처럼 WHERE 절의 조건에 맞는 새로운 행이 생길 수 있는 경우를 말한다.
-
트랜잭션 격리 수준(Transaction Isolation Level)에서 Phantom Read를 지원하면
새로운 유령(phantom)행이 나오지만
지원하지 않으면 새로 생긴 행을 볼 수 없다.
추가 정보
-
MySQL의 InnoDB 스토리지 엔진의 기본 Isolation Level이 REPEATABLE-READ이고
-
Oracle은 READ-COMMITED이다.
-
Oracle은 READ-COMMITED와 SERIALIZABLE만 지원하며 나머지 두가지 Isolation Level은 지원하지 않는다.
-
각 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