지난글 에서는 Transaction이 무엇인지에 대해서 한번 살펴보았다.
이번에는 지난번에 설명했던 ANSI에서 정의한 Transaction의 Isolation level 4단계에대해서 알아보자.

 

격리레벨 4단계를 이해하기위해 일단 상황을 가정해보자. 
 Table USER는 id와 name column이 있다.
 그리고 동시에 실행되는 processes a, b, c 가 있다고 가정해보자 a는 트렌젝션을 시작하고, 이것은 data를 insert하는데 commit될수도 있고, 커밋이 안될 수 도 있다. b는 SELECT 쿼리를 2번 사용하는 트랜잭션이다. c는 data를 select하고 update 한다. 이 모든 프로세스는 USER Table에서 실행된다고 가정하자.

 

READ UNCOMMITTED 
* b = (select * from user);
 이 레벨은 table에 락을 걸지 않는다. 이 말인즉슨 A가 USER table에 {id:user10,name:홍길동}을 insert하는 도중에 (권한 처리를 위해  아직 uncomitted되었다.)  B가 SELECT를 한다면 이 Uncommitted 되는 {id:user10,name:홍길동}을 본다는  이야기이다.(Dirty Read) 심지어 a가 rollback 되었음에도 B의 SELECT 결과 에는 사용된다. 이는 가장 빠르긴하지만, 안전하지않다. 

 

READ COMMITTED
 * b = (select * from user where id='user10');
 이 레벨에서는 커밋된 데이터에 락을건다. 커밋된 데이터만 읽을수 있지만, c가 만약 트랜젝션중간에 update를 하고 commit을 하면, b가 1회에 select한 데이터가 2회에는 달라질수가 있다(Non repeatable read). 예를들어보자. b 트랜젝션에서 {id:user10, name:홍길동} 데이터를 1회 읽었다. 그런데 c transaction에서 user10의 이름을 '김길동'이라고 바꿨다. 다시 b에서 2회 select를 실행했을땐 {id:user10, name:홍길동} 을 읽게된다.

REPEATABLE READ
 * b = (select * from user where name='홍길동');
 이 레벨에서는 block of SQL의 lock을 건다. 만약 현재 USER TABLE에 {user:aaa,name:홍길동}, {user:bbb,name:홍길동}이 있다고 가정하자. 그런데 a 트랜잭션에서 도중에 {user:ccc, name:홍길동}을 넣고 commit 했다. 그리고나서 b가 2회째 select를 수행하게되면 1회째와 달리 총 3개의 행을 select 하게된다.(Phantom read)

 

SERIALIZABLE
 이 레벨은 전체 테이블을 잠근다(위의 예제는 b가 select를 2번 실행할동안 table 전체를 lock 한다.) 이것은 가장 안전하지만, 비효율적이고 가장 느린데이터 작업방법이다. 

 


위의 내용들 참고하여 transaction isolation level에 따른 나타날수 있는 현상을 정리하자면 다음과 같다.

  Dirty Read Non repeatable read Phantom read
READ UNCOMMITTED 
Permitted Permitted Permitted
READ COMMITTED
x Permitted Permitted
REPEATABLE READ
x x Permitted
SERIALIZABLE
x x x

 

출처
https://stackoverflow.com/questions/16162357/transaction-isolation-levels-relation-with-locks-on-table

https://stackoverflow.com/questions/11043712/what-is-the-difference-between-non-repeatable-read-and-phantom-read

+ Recent posts