초보 개발자

DB isolation level 본문

카테고리 없음

DB isolation level

taehyeki 2025. 4. 12. 17:49

DB의 transaction는 4가지를 준수한다.

ACID라는 것이있다. 

 

Atomic

Currency

Isolation

D

 

이 4가지를 통해서 DB는 반드시 어떠한 일이 일어나도 값의 정합성을 지킬 수 있다 (트랜잭션의 내부 중 커밋 되기 전 어떠한 에러가 발생(자연재해, 에러...)하면 절대 입력하지않음, 반대로 커밋이 일어나면 어떠한 일이 일어나더라도 반드시 트랜잭션 내용이 반영됨 ) 

 

A연결 B연결이 있다고 가정하고, 각 연결안에서 테이블을 업데이트하는 트랜잭션을 실행시킨다고가정하자.

Isolation은 각 연결 상에서의 발생하는 일련의 트랜잭션에서, 커밋이 된 값을 이용하는 것이다.  커밋이 되기 전의 어떠한 변경도 다른 트랜잭션에는 영향이 없음.

 

다만 isolateion에는 4가지의 레벨이 존재하고, 각 DB는 4개의 레벨중 하나의 값을 디폴트로 가진다 (이는 디비에 따라 상이)

 

트랜잭션을 실행할 때 마다 각 레벨을 지정해줄 필요가 있다 (  mysql경우에는 트랜잭션이 시작되기 전에 isolation 세션을 만들고 트랜잭션이 끝난 뒤 그 세션을 종료해주어야한다 )

각 레벨을 지정할 경우 어떠한 일이 발생하는지 서술한다.

 

각 레벨에서는 읽는 방법이 조금씩 다른데, 

Dirty Read

A연결상에서 트랜잭션을 사용해서 테이블의 값을 변경 중에 있을때, ( 중요 ! 커밋 발생하지 않은 상태 ) B연결상에서 그 값을 읽어들였을 때 변경된 값이 조회된다. 

 

다만, B연결에서 트랜잭션이 일어나는 중에 A연결에서 커밋이 발생하면 B연결에서는 커밋 된 이후의 값으로 바뀌어 보임 )

 

postgresql에서는 허용하지 않음 즉 트랜잭션 중의 변경된 값은 다른 트랜잭션에서는 변경사항을 반영하지 않음 

 

유효화했을경우 :

유효화 하지 않았을 경우 :

 

Norepeatable read

값이 변경 되었을 때 커밋이 일어나더라도, 트랜잭션이 발생하였을 때의 값을 유지함. 즉 B연결에서 트랜잭션이 일어나는 중에 A연결에서 커밋이 발생하더라도, 커밋이 일어나기 전의 값으로 읽힘

 

이 값이 저장되는 시점은 트랜잭션 시작 절 (begin)도 아닌, isolation 레벨 선언 절(set isolation ....)도 아닌 , 처음 명령어가 실행된 시점이다 ( Select , update... ) 

다만 이 값은 Update에 의한 변경이며 따라서 특정 행의 값이 바뀌는 경우

 

유효화했을경우 :

유효화 하지 않았을 경우 :

 

phantom read

Nonrepeatable read와 비슷한데, 다만 대상이 특정 행의 값이 아니라, 특정 행의 갯수이다.

따라서 이 현상은 Delete 및 Insert에서 발생한다.

 

 

 

유효화했을경우 :

유효화 하지 않았을 경우 :

 

예를들어서, A연결의 트랜잭션과 B연결의 트랜잭션이 실행되고 있을 경우에, B트랜잭션에서 어떤 테이블의 행수를 읽었을 때 10개 였고, A트랜잭션에 의해서 행이 하나 삭제되어 9개로 바뀐경우에(혹은 추가되어 11개로 바뀐경우 )B트랜잭션에서 10개에서 바뀐 9개의 값을 참조할 수 있다는 것이다. 

 

postgresql에서는 허용하지 않음 즉 다른 연결 상에서 트랜잭션 내에서 행이 추가 삭제 되더라도 현재 연결의 트랜잭션 내에서는 추가 및 삭제 되기 전의 행 수로 계산

 

serialization Anomaly