[MySQL] 격리 수준

Fortice·2021년 10월 14일
1

MySQL

목록 보기
5/5
post-custom-banner

MySQL의 격리 수준

트랜잭션의 격리 수준이란 여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지 말지를 결정하는 것이다.

READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE 4가지로 나뉜다. 뒤로 갈수록 고립성이 높아지며, 동시 처리 성능이 떨어진다.

부정합 문제DIRTY READNON-REPEATABLE READPHANTOM READ
READ UNCOMMITTED발생발생발생
READ COMMITTED없음발생발생
REPEATABLE READ없음없음발생(InnoDB는 없음)
SERIALIZABLE없음없음없음

DIRTY READ, NON-REPEATABLE READ, PHANTOM READ

  • DIRTY READ
    • 아직 커밋되지 않은 수정 중인 데이터를 다른 트랜잭션에서 읽을 수 있도록 허용할 때 발생한다.
    • 변경 도중 읽고 변경 사항이 롤백 될 경우 중간에 읽은 데이터가 DIRTY 데이터
    • (T1) UPDATE > (T2) SELECT > (T1) ROLLBACK
  • NON-REPEATABLE READ
    • 한 트랜잭션 내에서 같은 쿼리를 두번 수행할 때, 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제함으로써 두 쿼리가 상이하게 나타나는
      비 일관성이 발생하는 것을 말한다.
    • (T1) SELECT > (T2) UPDATE > (T1) SELECT
  • PAHNTOM READ
    • 한 트랜잭션 안에서 일정범위의 레코드를 두번 이상 읽을 때, 첫 번재 쿼리에서 없던 유령 레코드가 두번째 쿼리에서 나타나는 현상을 말한다.
    • (T1) SELECT > (T2) INSERT > (T1) SELECT

1. READ UNCOMMITTED

트랜잭션에서의 변경 내용이 COMMIT이거나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.

2. READ COMMITTED

오라클 DBMS에서 기본으로 사용되는 격리 수준이고, 온라인 서비스에서 가장 많이 선택된다. 어떤 트랜잭션에서 데이터를 변경했더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회 할 수 있다.

3. REPEATABLE READ

InnoDB 스토리지 엔진에서 기본으로 사용하는 격리 수준이다. 바이너리 로그를 가진 MySQL 서버에서는 최소 이 격리 수준 이상을 사용해야한다. 트랜잭션이 ROLLBACK 될 가능성에 대비해 변경되기 전 레코드를 언두 공간에 백업해두고 실제 레코드 값을 변경한다. READ COMMITTED와의 차이는 몇 번째 이전 버전까지 찾아 들어가야 하느냐이다.

트랜잭션은 생성된 순서대로 오름차순의 ID를 갖는데, 언두 로그에 트랜잭션 ID를 기록해 본인 트랜잭션의 ID보다 작은 로그를 참조한다.

INSERT 시 PHANTOM READ가 왜 생길까?
언두 로그에 트랜잭션 ID를 저장해 높은 ID를 가진 트랜잭션의 INSERT도 참조 안할줄 알았다. 책에서는 SELECT FOR UPDATE 문으로 쓰기 잠금을 걸면서 읽는데, INSERT된 언두 로그는 잠금을 걸수가 없어서 현재 상태의 데이터를 읽게 된다.

언두 로그는 잠금을 걸수가 없어서 현재 상태의 데이터를 읽게 된다. 이 문장이 이해가 안된다. 추측하기로는 SELECT FOR UPDATE 쿼리는 이미 쓰여진 레코드들에 쓰기 락을 거는데, 위 규칙에 따라 언두 로그를 참조하려 했지만, 쓰기 잠금이 불가능해 자연스럽게 현재 데이터를 읽었다 는 의미 같다.

InnoDB의 경우 Undo 로그로 REPEATABLE READ 격리 수준에서도 PHANTOM READ가 발생하지 않는데 SELECT FOR UPDATE의 특징 때문에 발생할 수 있다.

4. SERIALIZABLE

읽기 작업도 읽기 잠금이 무조건 걸려야 한다. 따라서 같은 읽기 작업이 아니라면 트랜잭션을 모두 기다리므로 성능이 저하된다.

profile
서버 공부합니다.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2022년 4월 1일

좋은 설명 이네요~ 👍

답글 달기