[DB] 트랜잭션 격리 수준

다은·2025년 11월 2일

DB

목록 보기
6/7
post-thumbnail

트랜잭션 격리 수준

  • 동시에 여러 트랜잭션을 수행할 때, 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용할지 말지를 결정함
  • 격리 수준이 낮을 수록 동시성이 높아지고 오버헤드가 줄어드나, 일관성이 떨어짐

READ UNCOMMITTED

  • 커밋되지 않은 트랜잭션의 결과를 볼 수 있음
  • 성능이 좋지 않기 때문에 실제로 거의 사용되지 않음
  • 정합성 측면에서 문제가 많음

👀 Dirty Read
커밋되지 않은 데이터를 읽음


READ COMMITTED

  • MySQL을 제외한 대부분 DB의 기본 격리 수준
  • 트랜잭션이 시작된 후 커밋된 트랜잭션으로 인한 변경 사항 확인 가능
  • fuzzy read
  • 커밋될 때까지의 변경 사항은 다른 사람에게 표시되지 않음

👀 Nonrepeatable Read
동일한 명령문을 두 번 실행했을 때 다른 데이터를 볼 수도 있음


REPEATABLE READ

  • MySQL의 기본 트랜잭션 격리 수준
  • 트랜잭션이 레코드에 최초로 접근하기 전에 커밋된 데이터만 확인 가능
  • 트랜잭션이 읽는 모든 행이 동일한 트랜잭션 내에서 후속 읽기에서 동일하게 보이도록 함

👀 Phantom Read
동일한 트랜잭션에서 동일한 값에 대해 여러 번 조회 쿼리를 수행했을 때, 존재하던 레코드가 사라지거나 없어지는 현상

조회쿼리를 수행하는 과정에서 다른 트랜잭션에서 레코드 insert / delete를 수행하고 커밋했을 경우, 해당 내용이 반영됨


SERIALIZABLE

  • 트랜잭션이 충돌하지 않도록 강제로 트랜잭션을 정렬함 → 팬텀 리드 해결
  • 읽는 모든 행에 잠금 설정
    • 먼저 레코드를 읽은 트랜잭션이 종료되기 전에 다른 트랜잭션에 해당 레코드에 대해 커밋하지 못하게 강제함
격리 수준Dirty ReadNonrepeatable Read팬텀 리드잠금 리드
READ UNCOMMITTEDOOOX
READ COMMITTEDXOOX
REPEATABLE READXXOX
SERIALIZABLEXXXO



💡 MySQL의 Repeatable read 수준에서는 Phantom Read가 발생하지 않는다!

  • MySQL의 기본 격리 수준은 Repeatable read이며, 해당 격리 수준은 Phantom read가 발생할 수 있으나, mysql은 MVCC 덕분에 발생하지 않음
  • MySQL은 MVCC를 이용해 값을 업데이트 할 경우, 언두로그에 기존 내용을 기록함
  • 다른 트랜잭션은 레코드가 아니라 언두로그의 내용을 조회하기 때문에 일관성 있는 데이터를 확인할 수 있음
  • SELECT … FOR UPDATE 문을 수행할 경우, 예외적으로 phantom read가 발생할 수 있음
    • 변경 쿼리처럼 exclusive lock을 거는데, 언두 레코드에는 락을 걸 수 없어 실제 레코드에 락을 걸고 실제 레코드값을 가져오게 됨



profile
CS 마스터를 향해 ..

0개의 댓글