2009년 4월 15일 수요일

InnoDB - 트랜잭션4

○4개의 트랜잭션 분리레벨

여러개의 클라이언트가 동시에 같은 테이블에  대해서 트랜잭션처리를 실행하는 경우는 데이터의 조회, 저장의 동작이 문제가 되곤 한다. 
이것을 ANSI/ISO SQL규격에서 규정한 것이 「트랜잭션 분리레벨」이다. 

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE
InnoDB는 이 4개의 트랜잭션 분리레벨을 전부 지원하고 있다. 
그러나 NDB하고 BDB는 READ COMMITTED만을 지원하고 있다. 

MySQL에서는 SQL문에서 사용하는 트랜잭션 분리레벨을 지정가능하다. 
이 4개의 트랜잭션 분리레벨에 대한 데이터의 조회방법의 차이는 다음과 같다. 

 dirty readnon repeatable readphantom read
READ UNCOMMITTEDooo
READ COMMITTEDxoo
REPEATABLE READxxo
SERIALIZABLExxx

o:발생을 허가, x:발생하지 않음

1. dirty read
여러 개의 클라이언트가 동시에 테이블에 접속해 있다고 하자. 
이 때 한쪽에서 아직 COMMIT하고 있는 데이터를 다른 한쪽에서 조회가 가능한 상황이 dirty read이다. 

2. non-repeatable read (반복불능 조회)
여러 개의 클라리언트가 동시에 테이블에 접속해 있다고 하자. 
한쪽(A)이 어떤 레코드를 SELECT하고 다른 한쪽(B)가 A가 SELECT한 레코드를 갱신하고 COMMIT한다. 
여기에서 다시 A가 같은 레코드를 SELECT했을 때  값이 B가 변경한 것으로 변해 있는 상황이 non repeatable read이다. 
다시 말하면 지난번 조회내용과 이번 조회내용이 다르다는 것이다. 

3. phantom read
non-repeatable read가 UPDATE에 관한 사항이었던 것에 비해 phantom read는 INSERT에 관한 사항이다. 
한쪽(A)이 어떤 레코드를 SELECT한 후 다른 한쪽(B)가 새로운 레코드를 INSERT하고 COMMIT한다고 하자.  여기에서 다시 A가 같은 조건으로 레코드를 조회할 경우 B가 추가한 새로운 레코드도 조회되는 상황이 phantom read이다. 
지난번 조회내용과 이번 조회내용이 다르다.


InnoDB에서는 REPEATABLE READ대해서 phantom read는 발생하지 않는다. 
또 InnoDB의 SERIALIZABLE는 lock방법을 명시하지 않은 모든 SELECT문을 
SELECT ... LOCK IN SHARE MODE로서 취급한다.