Spring

트랜잭션 격리 수준

트랜잭션 격리 수준

데이터베이스에 N개의 트랜잭션을 동시에 처리하다 보면 같은 데이터에 접근할 수 있다.

 

트랜잭션의 목적은 로직의 흐름 속에서 데이터를 일관되게 처리하기 위한 것이나, 동시에 같은 데이터에 write 접근을 하는 경우엔 문제가 될 수 있다.

 

이러한 상황에서 트랜잭션에서 일관성이 없는 데이터를 허용하도록 하는 수준을 말한다.

 

단순하게 생각하면 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다.

 

 

격리수준에는 4가지가 있다.

  • READ_UNCOMMITED (level 0)
  • READ_COMMITED (level 1)
  • REPEATABLE_READ (level 2)
  • SERIALIZABLE (level 3)

격리 수준이 높아질수록 동시성(Concurrency)은 높아지고 속도는 느려진다.

 

아래의 명령어를 통해서 격리 수준을 확인 수 있습니다.

SHOW VARIABLES like 'tx_isolation';

 

READ_UNCOMMITED (커밋되지 않는 읽기, level 0)

  • 트랜잭션 처리중 or 아직 commit되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용
  • 어떤 사용자가 A라는 데이터를 B로 변경하는 동안 다른 사용자는 B라는 아직 완료되지않은(Uncommitted 혹은 Dirty) 데이터 B를 읽을 수 있다.

Dirty read 발생

다른 트랜잭션에서 처리하는 작업이 완료되지 않았는데도 다른 트랜잭션에서 읽을 수 있는 현상

READ_UNCOMMITED 격리수준에서만 발생

 

READ_COMMITED (커밋된 읽기, level 1)

  • dirty read 방지 : 트랜잭션이 commit 되어 확정된 데이터만을 읽도록 허용
  • A라는 데이터가 B로 변경되는 동안 다른 사용자는 해당 데이터에 접근할 수 없다.
  • 랜잭션내에서 똑같은 SELECT를 수행했을 경우 다른 결과를 반환할 수 있다.
  • 오라클 DBMS에서 기본으로 사용하고 있고, 온라인 서비스에서 가장 많이 선택되는 격리수준이다.

 

REPEATABLE_READ (반복 가능한 읽기, level 2)

  • 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회할 수 있는 격리수준
  • 데이터를 변경하려고 하면 UNDO 영역에 백업해두고 실제 레코드를 변경

Phantom READ 발생

트랜잭션이 데이터를 두 번 읽는다고 가정 할 때 where 절의 조건에 맞는 레코드가 추가로 생성될 때,

새로운 "유령(phantom)"행이 나오지만 phantom read를 지원하지 않으면 새로 생긴 행을 볼 수 없다.

 

SERIALIZABLE (직렬화 가능, level 3)

  • 완벽한 읽기 일관성 모드 제공(가장 엄격함)
  • 트랜잭션이 특정 테이블을 읽으면 다른 트랜잭션은 그 테이블의 데이터를 추가/변경/삭제할 수 없다.
  • 성능 측면에서 동시 처리성능이 가장 낮다.
  • 거의 사용되지 않는다.
  • 데이터의 일관성 및 동시성을 위해 MVCC(Multi Version Concurrency Control)를 사용하지 않음

MVCC

다중 사용자 DB 성능을 위한 기술

데이터 조회시 LOCK을 사용하지 않고, 데이터의 버전을 관리해 데이터의 일관성 및 동시성을 높이는 기술