DB 트랜잭션 격리 수준(Transaction isolation)

in #kr6 years ago

Thread에서 공유 자원에 동시 접근을 제한하기 위해 Lock을 걸듯이 DB에서도 트랜잭션들 간에 같은 동일한 데이터에 대한 동시 접근을 제한하기 위하여 Lock을 설정할 수 있다. Lock을 건다는 것은 그만큼 동시처리량이 줄어든다는 의미이기 때문에 과도하게 사용하면 성능에 문제가 생길 수 있다. 따라서 상황별로 꼭 필요한 수준의 Lock을 걸어서 정합성을 유지하고 최대한의 성능을 내기 위해서는 동시성 이슈가 발생할 수 있는 상황들을 정확히 정의하여 구분하는 것이 매우 중요하다.

다음에 설명하고있는 트랜잭션 격리 수준(Transaction isolation level)을 통해 이 부분을 명확히 정의 할 수 있다.

DB 트랜잭션 격리 수준(Transaction isolation level)에 따른 동시성 이슈

가장 낮은 isolation 레벨 0의 경우 lock이 걸리지 않기때문에 속도는 매우 빠르나 동시 접근을 허용하기때문에 데이터 정합성에 문제가 생길 수 있고, 반대로 가장 높은 레벨3의 경우 완전히 lock을 걸어 동시 접근을 차단하고 순차적으로 처리 (serializable) 하기 때문에 정합성은 완벽하지만 동시에 처리 할 수 있는 양이 적어 속도가 매우 느리다.

아래 표를 보면서 각각의 transaction isolation level에서 어떤 동시성 이슈들이 발생할 수 있는지 동시성 이슈에 대한 설명과 함께 읽어보면 쉽게 이해할 수 있다.

Isolation LevelDirty ReadNonrepeatable ReadPhantom Read
레벨0 Read Uncommited발생발생발생
레벨1 Read CommittedX발생발생
레벨2 Repeatable ReadXX발생
레벨3 SerializableXXX

앞서 여러번 말했듯이 동시성 이슈란 하나 이상의 트랜잭션이 동시에 동일한 데이터에 접근하여 읽기/쓰기 오퍼레이션을 할 때 발생 할 수 있으므로 이 상황을 머리 속에 넣어두고 어떤 문제가 발생할지 상상한 후 다음 이슈들을 살펴보자.

Dirty Read

  • 트랜잭션1에서 A테이블을 SELECT 한 후 트랜잭션2에서 A테이블 내용을 변경하는 상황 가정
  • 트랜잭션2가 해당 변경사항을 commit 하지도 않았는데, 트랜잭션1에서 다시 A테이블을 SELECT하면 해당 변경사항을 읽어들일 수 있게됨

Non-Repeatable Read (Inconsistent Read)

  • 트랜잭션1에서 A테이블을 SELECT 한 후 트랜잭션2에서 A테이블 내용을 변경(UPDATE)하는 상황 가정
  • 트랜잭션2가 해당 변경사항(UPDATE)을 commit 한 이후에, 트랜잭션1에서 다시 A테이블을 SELECT하면 해당 변경사항을 읽어들일 수 있게됨

Phantom Read

  • 트랜잭션1이 A테이블에서 SELECT한 이후 트랜잭션2에서 A테이블에 내용을 추가/삭제(INSERT/UPDATE)하는 상황 가정
  • Repeatable Read가 보장된 경우, A테이블에서 SELECT해왔던 데이터들을 다른 트랜잭션2가 수정(UPDATE)하여 commit한 후 트랜잭션1에서 다시 A테이블을 SELECT 하더라도 트랜잭션2의 수정내용을 읽어들일 수 없다.
  • 하지만 트랜잭션2가 추가/삭제(INSERT/DELETE)를 한 경우, 다시 A 테이블에서 SELECT하게되면 기존에 A에서 SELECT했던 데이터에서 row가 추가되거나 사라질 수 있다.(유령 데이터)

Coin Marketplace

STEEM 0.30
TRX 0.11
JST 0.033
BTC 64106.00
ETH 3129.71
USDT 1.00
SBD 4.16