Transaction Isolation Level
트랜잭션 격리 수준 이해하기
  • Database

Transaction Isolation Level

  • 동시에 여러 트랜잭션이 실행될 경우에, 각 트랜잭션이 다른 트랙잭션에서 변경되거나 조회하는 데이터를 볼 수 있도록 허용할지에 대한 정책레벨
  • 격리수준 종류 : Read Uncommitted, Read committed, Repeatable Read, Serializable
  • 격리 수준이 높아질 수록 동시성은 떨어지고, 반대로 격리수준이 낮아질 수록 동시성이 높아지는것이 일반적이다.

Read uncommitted (Dirty Read)

  • 일반적으로 많이 사용되지 않는 격리수준
  • 변경내용이 commit이나 rollback에 상관없이 다른 트랙잭션에서 보여질 수 있음
  • 어떤 트랜잭션이 종료되지 않은, 실행중일 때에도 다른 트랙잭션에서 데이터가 보여질 수 있는 문제가 있음
  • Dirty Read를 유발하는 Read Uncommitted는 RDBMS표준에서는 격리수준으로 인정하지 않을 정도로 데이터의 정합성에 문제가 있음
  • Dirty Read, Non-repeatable read, Phantom read 현상 발생

Read Committed

  • Oracle에서 기본적으로 사용되는 격리수준
  • 온라인서비스에서 가장 많이 선택되는 격리수준으로 데이터를 변경하였더라도 commit 혹은 rollback 이 완료된 데이터만 다른 트랙잭션에서 접근 가능
  • 어떤 트랙잭션에서 처리한 작업이 commit혹은 rollback이 되어있지 않다면 다른 트랙재션에서는 undo영역에 있는 데이터를 보여줌
  • Read Committed 격리수준에서도 Non-Repeatable (Repeatable Read 불가능)이라는 부정합이 발생할 수 있음
Repeatable Read : 하나의 트랙잭션내에서 동일한 select 쿼리를 실행했을 때는 항상 같은 결과를 가져와야 한다는 정합성 정의 (select 한 후 재차 select했을 때 데이터 변경이 있어서 다른 데이터가 조회되는것을 뜻함)

Non-Repeatable Read : 하나의 트랜잭션에서 같은 쿼리를 여러번 실행했을 때 다른 결과를 볼 수 있게 되는 현상

Repeatable Read

  • MySQL에서 기본적으로 사용되는 격리수준 (모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당 데이터데 대한 수정이 불가능)
  • Binary Log를 가진 MySQL의 장비에서는 최소 Repeatable read 격리 수준 이상을 사용해야함
  • Non-Repeatable Read 부정합이 발생하지 않음
  • InnoDB Storage Engine은 트랜잭션이 Rollback 될 가능성에 대비해 변경되기 전 레코드를 Undo 공간에 백업해두고 실제 레코드값을 변경 (MVCC-Multi Version Concurrency Control)
  • MVCC를 위해 undo 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있도록 보장 (Read committed도 commit 되기 전 데이터를 보여줌)
  • Repeatable Read와 Read committed의 차이는 undo 영역에 백업된 레코드의 여러 거번 가운데 몇 번째 이전버전까지 찾아 들어가야 하는지에 있음. 트랜잭션을 종료하지 않으면 undo 영역이 커질 수 있으므로 이로인해 MySQL 성능이 떨어질 수 있음
  • select .. for update 쿼리의 경우 다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다가 안보였다가 할 수 있음. 이것을 Phantom Read 라고 표현. undo 영역을 lock 할 수 없기 때문에 변경 전 데이터가 아닌 현재 변경된 레코드를 표현
MVCC (Multi Version Concurrency Control) : 잠금을 사용하지 않는 일관된 읽기를 제공하는 것이 목적

Read Uncommitted : 변경되었거나 안된 데이터의 값을 읽음
Read Committed : 변경 전 undo 영역에 있는 값을 읽음

이러한 과정을 MVCC라고 부름

Serializable

  • 동시성이 중요한 DB에서는 거의 사용하지 않음
  • 읽기 작업도 공유잠금(읽기 잠금)을 획득하여야만 하며, 동시에 다른 트랜잭션이 같은 레코드를 변경할 수 없게 함.
  • 한 트랜잭션에서 읽고 있는 레코드는 다른 트랜잭션에서는 접근할 수 없음

Repeatable Read 격리수준과 Read Committed 격리수준의 성능 비교

  • Repeatable Read 가 트랜잭션을 열어 해당 트랜잭션에서 모든 테이블의 데이터를 select한 후 그대로 놔두면 InnoDB undo영역이 계속 커져서 시스템 테이블스페이스 I/O가 유발되는 경우의 대표적으로 성능을 떨어뜨리는 경우
  • 해당 문제를 일으키지 않으면 성능상 차이가 거의 없음. Binary log가 활성화된 MySQL 서버에서는 Read Committed 격리 수준을 사용할 수 없음.