<추천글>[DB] Transaction의 Isolation level을 나눠 둔 이유

2021. 11. 29. 00:35[ Basic ]/# 데이터베이스

트랜잭션의 특징 (ACID)

 

  • 원자성 (Atomicity) : 트랜잭션의 수행 결과는 DB에 모두 반영되던가, 그렇지 않던가 둘 중 하나여야 한다.
  • 일관성 (Consistency) : 트랜잭션 수행 결과는 항상 일관성이 있어야 한다. 트랜잭션 시작 시에 참조한 DB상태를 기준으로 트랜잭션을 수행하고 트랜잭션 도중에 변경된 DB를 기준으로 하지 않는다. 따라서 사용자는 일관된 데이터를 볼 수 있도록 한다. 
  • 독립성 (Isolation) : 다수의 트랜잭션이 서로의 트랜잭션 연산에 끼어들 수 없다. 트랜잭션들끼리 동시에 수행될 수 없다는 의미가 아니다. 동시에 실행은 될 수 있으나 트랜잭션 도중의 결과를 다른 트랜잭션이 참조할 수 없다는 것을 의미한다. (serializable)
  • 지속성 (Durability) : 트랜잭션이 커밋되었다면 그 결과는 영구적으로 DB에 반영되어야 한다.

 

트랜잭션 격리 수준 (Isolation Level) : 설정 사항

오해하지 말하야 할 것은 isolation level은 "트랜잭션 단위로 설정한다"는 것이다.

 

cf. Serializability: 다수의 트랜잭션을들 섞어서 수행했음에도 불구하고 결과값은 우리가 의도했던 순차적인 과정으로 처리되었을 때랑 같을 때, serializable하다고 함.

1) READ_UNCOMMITTED (level 0) : not serializable

- 가장 약한 수준으로 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽을 수 있도록 허용한다. (dirty read 허용)

- 특정 트랜잭션이 데이터A 값을 데이터B로 바꾸었고 아직 커밋하지 않은 상태에서 다른 트랜잭션이 해당 데이터B값을 읽을 수 있도록 허용한다.(dirty read)

 

2) READ_COMMITTED (level 1) : not serializable

- 트랜잭션이 커밋된 데이터만 읽도록 한다. 즉, 커밋되기 전의 데이터는 읽지 못하도록 한다.(dirty read 방지)

 

[발생할 수 있는 문제점]

- B 트랜잭션에서 1번 회원의 주소를 조회 : 서울

- A 트랜잭션에서 1번 회원의 주소를 성남으로 변경하고 커밋

- B 트랜잭션에서 1번 회원의 주소를 조회 : 성남

 

-> 즉, repeatble read할 때 일관성이 깨짐.

 

3) REPEATABLE_READ (level 2) : not serializable

- 트랜잭션이 사용하는 모든 데이터에 lock이 걸려서 다른 트랜잭션이 갱신과 삭제를 할 수 없도록 한다. (삽입은 가능)

- 따라서 같은 데이터를 두 번 쿼리했을 때 일관성 있는 데이터를 제공한다.

 

예시1)

[T1]
update student set gpa = (1.1)*gpa
[T2]
select avg(gpa) from student

select max(gpa) from student

위와 같이 T1, T2가 수행된다고 가정하고 T2의 isolation level이 repeatable read 일 때, 같은 데이터를 반복해서 읽는 T2안에서는 항상 일관된 gpa를 읽어야하므로 T1이 수행되기 전이나 후에 값을 읽어오는 결과를 가져온다. 

 

예시2)

- B 트랜잭션에서 1번 회원의 주소를 조회 : 서울

- A 트랜잭션에서 1번 회원의 주소를 성남으로 변경하고 커밋

- B 트랜잭션에서 1번 회원의 주소를 조회 : 서울(기존 백업해둔 데이터를 가져옴)

 

-> 일관성 유지됨

 

 

4) SERIALIZABLE (level 3)

- 가장 엄격한 isolation level 이며 일관성(Consistency)을 보장한다.

- lock이 걸린 데이터에 수정이나 삭제 자체를 못하게 함

- serializable을 위한 오버헤드가 크므로 남발하면 안된다.

 

Isolation level을 나눠 둔 이유

대략적으로 결과를 빠르게 얻기 위함이다. serializable하게 하는 것은 오버헤드가 너무 크다. isolation level을 낮게 둘 수록, serialization을 위한 오버헤드가 줄어들고(serializable하지 않게 되고), concurrency 정도는 높아진다. 따라서 일관성(Consistency)을 어느정도 포기하고 대략적인 데이터를 빠르게 가져오고 싶을 때에는 트랜잭션의 isolation level을 여유롭게 풀어두자.

 

 

 

cf. DBMS별 default isolation level

MYSQL : REPEATABLE READ
ORACLE : READ COMMITTED
H2 : READ COMMITTED