Spring

[Spring] @Transactional - 2 isolation (격리수준)

코리늬 2020. 7. 9. 22:53

이전 글에서 트랜잭션 전파레벨에 대해서 알아보았다.

트랜잭션을 사용할 때, 전파레벨과 함께 따라오는 것이 격리수준이다.

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

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

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

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

이 둘의 균형을 잘 맞추는것이 중요하다.


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로 변경되는 동안 다른 사용자는 해당 데이터에 접근할 수 없다.

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

  • 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 shared lock이 걸린다.

    따라서, 다른 사용자는 해당 영역에 대한 데이터 수정이 불가능하다.

  • 선행 트랜잭션이 읽은 데이터는 트랜잭션이 종료될 때까지 후행 트랜잭션이 갱신하거나 삭제하는 것을 불허함으로써 같은 데이터를 두 번 쿼리했을 때 일관성 있는 결과를 리턴한다.

Phantom READ 발생

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

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

SERIALIZABLE (직렬화 가능, level 3)

  • 완벽한 읽기 일관성 모드 제공(가장 엄격함)
  • 성능 측면에서 동시 처리성능이 가장 낮다.
  • 거의 사용되지 않는다.
  • 데이터의 일관성 및 동시성을 위해 MVCC(Multi Version Concurrency Control)를 사용하지 않음
  • 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당하는 데이터에 대한 수정 및 입력이 불가능하다.

MVCC

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

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


각 DB 별 isolation

MYSQL : REPEATABLE READ
ORACLE : READ COMMITTED
H2 : READ COMMITTED

참고

https://taetaetae.github.io/2016/10/08/20161008/

https://lng1982.tistory.com/287

https://effectivesquid.tistory.com/entry/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-Isolation-Level

https://nesoy.github.io/articles/2019-05/Database-Transaction-isolation