본문 바로가기

CS/데이터베이스

트랜잭션 격리 수준

트랜잭션 격리 수준이란, 특정 트랜잭션이 변경하거나 조회하고 있는 데이터에 대해 다른 트랜잭션의 접근을 허용 여부를 결정하는 것이다.

트랜잭션 격리 수준에 따라 데이터 조회 결과가 달라질 수 있다.

트랜잭션의 격리 수준은 다음과 같이 4개로 구분된다.

 

  • Read Uncommitted (커밋되지 않은 읽기)
      
  • Read Committed (커밋된 읽기)
      
  • Repeatable Read (반복 가능한 읽기)
      
  • Serializable (직렬화 가능)

위로 갈수록 격리 수준이 낮아지며, 동시 처리 성능이 높아진다.

반면, 밑으로 갈수록 격리 수준이 높아지며, 동시 처리 성능은 낮아지지만 데이터 부정합 문제가 발생할 확률이 줄어든다.

트랜잭션 격리 수준에 따른 문제점

트랜잭션 격리 수준에 대해 알아보기 전, 트랜잭션 격리 수준에 따라 발생할 수 있는 문제점에 대해 알아보자.

InnoDB 버퍼풀
변경된 데이터를 디스크에 반영하기 전까지 잠시 버퍼링 하는 공간

Undo Log
변경되기 이전 데이터를 백업해 두는 공간
트랜잭션 보장 (Rollback 시 Undo Log에 백업된 데이터를 복원)
트랜잭션 격리 수준 보장 (트랜잭션 격리 수준에 맞게 백업된 데이터 반환)

Redo Log
변경된 데이터를 백업(Commit 완료된 데이터)
영속성 보장 (서버 비정상 종료 시, Redo Log에 백업된 데이터 복원)

 

더티 리드 (Dirty Read)

특정 트랜잭션에 대해 데이터가 변경되었지만, 아직 커밋되지 않은 상황에서 다른 트랜잭션이 해당 변경 사항을 조회할 수 있는 문제를 말한다. 

 

이 문제는 트랜잭션 A가 데이터를 변경하고 커밋되지 않은 시점에 트랜잭션 B가 변경된 데이터를 읽어온 상황에서, 트랜잭션 A가 변경 내용을 커밋하지 않고 롤백한 상황에서 문제가 된다. 트랜잭션 B는 무효가 된 값을 읽게 되는 것이다.

 

반복 불가능한 조회 (Non-Repeatable Read)

같은 트랜잭션 내에서 같은 데이터를 여러 번 조회했을 때, 읽어온 데이터가 다른 경우를 의미한다.

트랜잭션 A가 T 테이블을 조회한 후, 트랜잭션 B가 T 테이블 내용을 변경한다고 가정해 보자.

트랜잭션 B가 해당 변경 사항을 커밋한 이후에, 트랜잭션 A가 다시 T 테이블을 조회하면 이전의 값과 일치하지 않게 된다.

 

팬텀 리드 (Phantom Read)

같은 트랜잭션 내에서 조회해 온 결과의 행이 새로 생기거나 없어지는 현상이다.

트랜잭션 A가 T 테이블에서 조회한 이후 트랜잭션 B에서 T 테이블에 내용을 추가/삭제하는 경우, 기존에 조회했던 데이터에서 새로운 행이 추가되거나 없어질 수 있다.

트랜잭션 격리 수준

그럼 이제 트랜잭션 격리 수준에 대해 알아보자.

 

  • Read Uncommitted
    커밋이 되지 않은 트랜잭션의 데이터 변경 내용을 다른 트랜잭션이 조회하는 것을 허용하는 격리 수준이다.
    데이터 부정합 문제가 발생할 확률이 높지만, 성능은 가장 빠르다.
    Dirty Read, Non-Repeatable, Phantom Read 현상이 발생한다.
    Oracle에서는 해당 격리 수준을 지원하지 않는다.
      
  • Read Committed
    커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회할 수 있도록 허용하는 격리 수준이다.
    특정 트랜잭션에서 데이터가 변경되었으나 아직 커밋되지 않은 상태라면, 다른 트랜잭션에서는 해당 데이터에 접근했을 때 트랜잭션 시작 전 데이터를 읽어온다.
    Non-Repeatable Read, Phantom Read 현상이 발생한다.
    Oracle, H2 등 대부분의 DBMS가 기본 모드로 해당 격리 수준을 사용한다.
      
  • Repeatable Read
    선행 트랜잭션이 읽은 데이터를 트랜잭션이 종료될 때까지 후행 트랜잭션이 갱신하거나 삭제하는 것을 불허함으로써 같은 데이터를 2번 조회했을 때 일관성 있는 결과를 반환하는 것을 보장하는 격리 수준이다.
    하지만, 행을 추가하는 것은 막지 않기 때문에 Phantom Read 현상은 발생한다.
    MySQL의 InnoDB엔진의 기본 격리 수준이다.
      
  • Serializable
    선행 트랜잭션이 읽은 데이터를 후행 트랜잭션이 갱신하거나 삭제뿐만 아니라, 중간에 새로운 레코드를 삽입하는 것도 막는 격리 수준이다. 가장 높은 데이터 정합성을 가지나, 성능은 가장 떨어진다.
    이 격리 수준에서는 단순한 조회 쿼리가 실행되더라도, DB에 락이 걸려 다른 트랜잭션에서 데이터에 접근할 수 없게 된다.

 

 

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

Redis  (0) 2023.06.28
RDBMS vs NoSQL  (0) 2023.06.27
트랜잭션과 Lock  (0) 2023.06.26
트랜잭션  (0) 2023.06.26
반정규화  (0) 2023.06.01