[db] transaction 격리 수준 - repeatable read(반복 읽기)

cochocho·2026년 2월 2일

db

목록 보기
5/6

repeatable read 격리 수준(반복 읽기)

snapshot 격리를 활용해 비반복 읽기 문제를 해결 가능


비반복 읽기 문제

transaction commit 이 완료된 값들만을 읽음에도 불구하고 다시 읽으면
그 값들이 달라져 불일치함
transaction commit 이 다른 transaction에서 또 발생했기 때문

commit 후 읽기(read committed) 격리 수준으로 해결되지 않는 문제로

  • 사용자 2가 계좌 1, 2의 1000원을 읽음
  • 사용자 1이 계좌 1의 1000원에서 500원을 계좌 2로 송금해
    계좌 1 : 500원, 계좌 2 : 1500원
  • 사용자 2가 읽은 계좌 2는 1500원
    따라서 총합을 이전 읽은 계좌 1 + 지금 읽음 계좌 2 = 2500원으로 합산하는 오류

몇초 후 사용자 2가 새로고침을 통해 정상 결과를 획득할 수 있음

이러한 경우는 지속적 문제가 아니면서 서비스에 따라 잠깐의 비정상 응답을 허용할 수 있음

그러나 특정 상황에서는 이러한 일시적 비정상 응답을 허용할 수 없는 경우도 있음

  • 데이터베이스 백업 시
    데이터베이스 백업을 위해 전체 복사본을 만들어야 하고 이에는 시간이 오래 걸림
    또한 백업 도중에도 데이터베이스에 쓰기 작업이 진행될 수 있음
    이때의 쓰기 작업은 자연스럽게 일부는 이전 버전의 데이터, 일부는 새로운 버전의 데이터를 백업 프로세스에게 반환해
    일관성이 깨진 데이터들을 저장하게 될 수 있다

  • 시간이 오래 걸리는 쿼리
    데이터베이스 전체 데이터를 기반으로 해당 작업들을 실행 시
    시간이 오래 걸릴 수 있는 작업으로
    이에 따라 커밋 후 읽기 격리 수준을 사용하게 되면
    일부는 이전 버전의 데이터를 보게 되며 일부는 이후 버전 데이터를 보게 되면서
    비정상적인 결과를 반환하게 될 수 있음
    - 통계 분석
    - 무결성 검사 쿼리 : 데이터가 로직상 올바른지 확인


snapshot 이란?

데이터베이스가 데이터마다 여러 버전의 값들을 유지해 각 트랜잭션마다 순서인 txid(transaction id)를 부여해
트랜잭션별로 읽을 수 있는 데이터를 특정 시점의 데이터로 고정한다
이후의 트랜잭션들에서 가해진 변경으로부터 데이터를 보호할 수 있는 것이다

사용자 1이 값을 계속 바꾸더라도 각 데이터 변경 시점을 버전별로 txid를 부여하고 관리함

사용자 2는 자신의 트랜잭션을 적용하는 시점을 해당 사용자 1과 동일하게 둘 수 있게 됨


snapshot 격리에서 데이터 version을 읽는 가시성 규칙

각 transaction id인 txid를 기반으로 데이터의 어느 버전까지 읽을 수 있는지를 결정하고
이를 통해 일관된 데이터의 snapshot을 제공하고 있음

  • transaction id(txid) 가 더 큰 transaction이 쓰거나 commit한 데이터는 현재 transaction에서 볼 수 없음
  • abort된 transaction이 쓰거나 commit한 데이터는 모두 현재 transaction에서 무시된다
  • db는 각 transaction을 시작할 때 그 시점에서 진행 중인 모든 transaction의 목록을 만든다

*이때 대상이 되는 transaction은 commit, abort 아직 완료되지 않은 모든 transaction

해당 transaction들이 쓰거나 commit한 데이터는 모두 현재 transaction에서 제외됨

=> 현재 transaction에게 무슨 일이 있어도 일관되고 고정된 데이터들을 읽을 수 있게 보장


snapshot 격리를 통해 볼 수 있도록 보장되는 데이터

  • 읽기를 실행하는 transaction이 시작한 시점에 읽으려는 데이터가 commit된 상태일 때

  • 읽으려는 데이터가 삭제된 것으로 표시되지 않았을 때

  • 삭제되었다고 표시는 되었으나 읽기를 실행한 transaction이 시작한 시점에 commit 되지 않았을 때


snapshot 격리의 성능상 이점

여러 버전의 데이터 유지가 필요할 뿐 읽기와 쓰기 작업이 서로를 차단하지 않으면서
오래 걸리는 작업에 대해 일관된 버전의 데이터를 처리하고 데이터의 일관성을 유지할 수 있다
이는 잠금 획득을 통해서만 작업을 수행하지 않아도 됨을 의미함

  • 읽는 쪽이 쓰는 쪽을 차단 x
    이전 버전의 일관된 데이터를 바라보는 것

  • 쓰는 쪽이 읽는 쪽을 차단 x
    이전 버전의 데이터를 수정하는 게 아니라 새로운 버전의 데이터를 추가하는 것

출처 : https://www.youtube.com/watch?v=sDSU8KrOcxc

0개의 댓글