먼저 데이터가 일관되지 않게 처리되는 상황을 확인해보면 아래와 같습니다.
낮은 단계의 트랜잭션 격리 수준에서 발생하는 현상
Dirty Read
다른 트랜잭션에서 처리 중인 내용이 완료되지 않았음에도, 트랜잭션에서 볼 수 있게되는 현상.
트랜잭션1 에서 A 테이블을 SELECT 한 후, 트랜잭션2 에서 A 테이블 내용을 변경하는 상황 가정.
트랜잭션2 가 해당 변경사항을 commit 하지도 않았는데, 트랜잭션1 에서 다시 A 테이블을 SELECT 하면 해당 변경사항을 읽어들일 수 있게 됩니다.
Non-Repeatable Read (Inconsistent Read)
트랜잭션 시작 후, 반복적인 조회작업에서 다른 트랜잭션에서 데이터가 변경되는 경우, 조회 시 데이터가 일치하지 않는 문제가 발생하는 현상.
트랜잭션1 에서 A 테이블을 SELECT 한 후, 트랜잭션2 에서 A 테이블 내용을 변경(UPDATE)하는 상황 가정.
트랜잭션2 가 해당 변경사항(UPDATE)을 commit 한 이후에, 트랜잭션1에서 다시 A 테이블을 SELECT 하면 해당 변경사항을 읽어들일 수 있게 됩니다.
Phantom Read
한 트랜잭션에서 일정 범위 내의 레코드를 두 번 이상 읽을 때, 첫번째 쿼리 조회 결과에서 없던 레코드가 조회되는 현상.
트랜잭션1 이 A 테이블에서 SELECT 한 이후, 트랜잭션2 에서 A 테이블에 내용을 추가/삭제(INSERT/UPDATE)하는 상황 가정.
Repeatable Read 가 보장된 경우, A 테이블에서 SELECT 해왔던 데이터들을 다른 트랜잭션2 가 수정(UPDATE)하여 commit한 후, 트랜잭션1 에서 다시 A 테이블을 SELECT 하더라도 트랜잭션2 의 수정내용을 읽어들일 수 없습니다.
하지만 트랜잭션2 가 추가/삭제(INSERT/DELETE)를 한 경우, 다시 A 테이블에서 SELECT 하게되면 기존에 A 테이블에서 SELECT 했던 데이터에서 row 가 추가되거나 사라질 수 있습니다. (유령 데이터)
-------------------------------------------------------------------------------------------------------------
트랜잭션 격리 수준 / 잠금 레벨 / locking level
Read Uncommitted (level 0)
커밋되지 않은 읽기, 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용.
A 라는 데이터를 B 라는 데이터로 변경하는 동안, 다른 사용자는 B 라는 (커밋 되지않은) 데이터를 읽을 수 있습니다.
Dirty Read, Non-Repeatable Read, Phantom Read 가 발생할 확률이 높습니다.
Read committed (level 1)
커밋된 읽기, 커밋되어 확정된 데이터를 다른 트랜잭션에서 읽는 것을 허용. : dirty read 방지.
A 라는 데이터를 B 라는 데이터로 변경하는 동안, 다른 사용자는 해당 데이터에 접근할 수 없습니다.
Non-Repeatable Read, Phantom Read 가 발생할 확률이 높습니다.
Repeatable Read (level 2) - MySQL InnoDB의 디폴트 격리수준
반복 읽기, 트랜잭션 내에서 한번 조회한 데이터가 반복적으로 조회 됩니다.
A 트랜잭션이 읽은 데이터는 트랜잭션이 종료될 때까지 B 트랜잭션이 갱신하거나 삭제하는 것을 허용하지 않음으로써 같은 데이터를 두 번 쿼리했을 때 일관성 있는 결과를 리턴 합니다.
SELECT col FROM a WHERE col1 BETWEEN 1 AND 10
을 수행하였고 결과는 두 건의 데이터 출력(col1 = 1 ,5).
다른 사용자가 col1 이 1 이나 5 인 row 에 대한 update 는 불가능합니다. 이를 제외한 나머지 범위에 해당하는 row 를 insert 하는 것은 가능.
Phantom Read 가 발생할 확률이 높습니다.
Serializable (level 3)
트랜잭션이 완료될 때까지 SELECT 문장에 사용하는 모든 데이터는 shared lock 이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능 합니다.
Dirty Read, Non-Repeatable Read, Phantom Read가 발생할 확률이 낮지만 동시 처리 성능은 크게 떨어질 수 있습니다.
MySQL InnoDB 의 디폴트 격리수준은 Repeatable Read 입니다.
격리수준 변경은 SET tx_isolation='격리수준이름' 으로 바꿀 수 있습니다.
'Tech > MySQL' 카테고리의 다른 글
MySQL - with(nolock) 같은 힌트 : isolation level 변경하기. (0) | 2019.06.10 |
---|---|
my.cnf 파일 위치 확인하는 방법 (0) | 2019.06.04 |
MySQL - 원격접속 안될때 (0) | 2019.06.03 |
Windows 2008 에서 Mysql 설치할때 Visual C++ Distribution 2013 에러나면 (0) | 2018.01.10 |
우분투에서 mysql 데이터 디렉토리 바꾸기 change data dir (0) | 2017.12.21 |