[DB] 트랜잭션 격리 수준

 트랜잭션 격리 수준이란 트랜잭션끼리 얼마나 고립되었는지를 나타내는 것이다. 트랜잭션 격리 수준이 높아질수록(트랜잭션 레벨이 높아질수록) 트랜잭션간의 고립도가 높아지는 대신 성능이 떨어지게 된다.

트랜잭션 레벨 0: READ UNCOMMITED
트랜잭션 레벨 1: READ COMMITED
트랜잭션 레벨 2: REPEATABLE READ
트랜잭션 레벨 3: SERIALIZABLE

 

이러한 트랜잭션 격리의 이유는 동시성 제어(Concurrency Control)때문이다. 동시성 제어란 DB 시스템에서 실행되고 있는 여러 개의 트랜잭션이 작업을 성공적으로 마칠 수 있도록 트랜잭션의 실행 순서를 제어하도록 하는 것. 이를 위해서 일부 트랜잭션에 변경이 생기더라도 하나의 트랜잭션이 시작되고 종료되기까지 데이터를 중도 변경 없이 일관되게 읽을 수 있어야 한다.

 

※ 트랜잭션 격리 수준에 따라 발생할 수 있는 문제 ※
Dirty Read(오손 읽기): 트랜잭션에서 변경이 일어난 후 commit되지 않은 값을 읽고, rollback후의 값을 다시 읽어 결과값이 상이
Non-Repeatable Read(반복불가능 읽기): 동일 쿼리를 두 번 수행했음에도 다른 트랜잭션의 값 수정에 의해 쿼리값이 다른 현상
Phantom Read(유령데이터 읽기): 동일 쿼리를 두 번 실행했을 경우, 첫 쿼리에 존재하지 않던 레코드가 두번째에는 나타나는 현상

 

 

 

0. READ UNCOMMITTED

트랜잭션의 커밋/롤백 여부에 관계없이 다른 트랜잭션이 읽는 것을 의미한다. 하나의 트랜잭션에 대해서 통일성이 전혀 보장되지 않아 부정합이 발생되므로 Dirty Read, Non-Repeatable Read, Phantom Read현상이 발생

 

 

 

1. READ COMMITTED - 커밋 단위로 공유락을 검 (커밋되면 공유락을 해제한다)

수정되고 있는 DB 테이블에서 값을 가져오는 것이 아니라 undo영역에 백업된 레코드에서 값을 가져오는 방법. commit되어 확정된 값만 읽으므로 Dirty Read는 발생하지 않지만, 트랜잭션 내에서 같은 select문을 실행하더라도 타 트랜잭션의 커밋 상태에 따라서(ex.트랜잭션A 실행중 트랜잭션 B가 커밋하여 undo영역에 변화 발생 시) 다른 결과가 출력되므로 Non-Repeatable Read, Phantom Read현상은 해결 불가능

실제 RDB에서 널리 사용하고 있는 방법이다.

 

 

 

2. REPEATABLE READ - 데이터의 update를 막음(insert 가능)

 트랜잭션이 시작되기 전에 COMMIT된 내용(undo영역에 존재하는 내용)에 대해서만 조회할 수 있는 격리수준이다. undo영역과 트랜잭션 실행 번호(순서)을 이용하여 트랜잭션 시작 전 시점의 스냅샷을 이용하기 때문에 dirty read나 non-repeatable read는 발생하지 않지만 여전히 phantom read현상은 발생한다.

 

 그런데 undo영역의 데이터를 이용하는데도 왜 phantom read가 발생할까?

> SELECT FOR UPDATE, LOCK IN SHARE과 같이 select하는 레코드에 쓰기 잠금을 걸어야 하는 쿼리들은 undo영역의 데이터에 쓰기 잠금을 걸 수 없기 때문에 테이블에 접근하게 된다.

 

 

3. SERIALIZABLE

선형 트랜잭션이 특정 테이블을 읽는 경우 공유 잠금을 걸어 다른 트랜잭션에서 해당 테이블에 데이터를 UPDATE/DELETE/INSERT 모두 불가능하게 한다.

'[ CS기초 ] > 데이터베이스' 카테고리의 다른 글

[DB] 트랜잭션, 동시성 제어, 락  (0) 2023.02.08
[DB] SQL문 문법 정리 - DML  (0) 2022.10.12
[DB] 관계 데이터 모델 기초  (0) 2022.09.17
[DB] 데이터베이스 개념  (1) 2022.09.10
[DB] JOIN  (0) 2022.01.04