[MySQL] MySQL 격리 수준

donghyeok·2022년 11월 28일
0

데이터베이스

목록 보기
5/5

격리 수준 (isolation level)

  • 트랜잭션의 격리 수준이랑 여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지 말지를 결정하는 것이다.
  • 격리 수준은 크게 READ UNCOMMITED, READ COMMITED, REPEATABLE READ, SERIALIZABLE의 4가지로 나뉜다.
  • READ COMMITED는 거의 사용하지 않고 SERIALIZABLE 또한 동시성 문제 때문에 거의 사용되지 않는다.
  • 데이터베이스의 격리 수준에 언급되는 세가지 문제점이 있다. 이는 레벨에 따라 발생할 수도 있고 아닐 수도 있다.
  • 일반적으로 MySQL은 REPEATABLE READ, 이외 DBMS에서는 READ COMMITTED를 사용한다.
DIRTY READNON-REPEATABLE READPHANTOM READ
READ UNCOMMITED발생발생발생
READ COMMITEDX발생발생
REPEATABLE READXX발생(InnoDB 예외)
SERIALIZABLEXXX

1. READ UNCOMMITED

  • READ UNCOMMITED 격리 수준에서는 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 관계없이 다른 트랜잭션에서 보인다.
  • 이러한 격리 수준의 문제는 COMMIT 되지 않은 불완전한 데이터를 가지고 로직을 수행한다는 점이다. (DIRTY READ)

2. READ COMMITED

  • READ COMMITED 격리 수준은 오라클 DBMS의 기본 격리 수준이다.
  • 해당 격리 수준에서는 특정 트랜잭션에서 COMMIT 되기 이전까지는 다른 트랜잭션에서 언두 로그 백업 데이터를 읽어 데이터의 일관성을 보장하려 한다.
  • 하지만 위 상황처럼 사용자B에게 있어 트랜잭션 내의 같은 쿼리가 다른 결과를 낼 수 있는 부정합의 문제가 있다. (NON-REPEATABLE READ)

3. REAPEATABLE READ

  • REPEATABLE READ는 MySQL의 기본 격리 수준이다.
  • 해당 격리 수준에서 역시 언두 로그를 활용해 MVCC 방식을 사용하는데 READ COMMITED와 다르게 언두 영역의 여러 버전 중에 선택하는 방식이 다르다.
  • 모든 트랜잭션에는 번호가 있으며 순차적으로 증가한다. 이를 이용해 자신의 트랜잭션 번호보다 작은 트랜잭션 번호에서 변경된 내용만 보도록 언두 로그를 선택한다.
  • SELECT ... FOR UPDATE 쿼리는 예외로 SELECT하는 레코드에 쓰기 잠금을 걸어야 하는데, 언두 레코드에는 잠금을 걸 수 없기 때문에 현재 언두 영역이 아닌 현재상태의 레코드를 가져와야하는데 이 때문에 동일 트랜잭션 내에서도 해당 쿼리의 결과가 다를 수 있다. (PHANTOM READ, InnoDB 예외 : 갭락, 넥스트 키락 덕분에..)

4. SERIALIZABLE

  • 해당 격리 수준에서는 select 쿼리 역시 공유 잠금(읽기 잠금)을 획득하며 동시에 다른 트랜잭션이 해당 레코드를 변경할 수 없다.
  • 해당 격리 수준은 InnoDB의 메뉴얼에 나타나는 "Non-Locking consistent read" (잠금이 필요 없는 일관적 읽기)에 위배되고 동시성이 매우 떨어져 잘 쓰지 않는다.

0개의 댓글