JPA에서 Transaction의 Isolation Level은 어떤 것이 있나요 각각 어떤 특징을 가지고 있나요

kkambbak1·2024년 1월 10일

https://devocean.sk.com/blog/techBoardDetail.do?ID=163799
https://www.youtube.com/watch?v=cc4M-GS9DoY&t=505

@Transactional 에는 2가지 중요 옵션을 사용할 수 있다.

  • propagation: 이는 세션의 트랜잭션을 어떻게 이용할지에 대한 설정이다.
    - REQUIRED, SUPPORTS, MANDATORY, NEVER, NOT_SUPPORTED, REQUIRES_NEW, NESTED 가 있다.
  • isolation: JPA상에서 DB Isolation을 지정할 수 있다.
    - DEFAULT, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE 가 있다.

isolation

여러 트랜잭션이 진행될 때, 트랜잭션의 작업 데이터를 타 트랜잭션에게 어떻게 노출할지 결정

default는 현재 사용중인 데이터 접근기술, DB드라이버의 기본 설정을 따름.
MySQL은 REPEATABLE_READ를, Oracle은 READ_COMMITED를 기본 격리 수준으로 가짐.

Isolation관련 용어

  • Dirty Read: 현재 트랜잭션에서 커밋되지 않은 변경 데이터를 다른 트랜잭션이 읽을 수 있음
  • Nonrepeatable Read: 가장 먼저 데이터를 읽은 데이터가, 다른 트랜잭션에서 변경을 했고, 이후 다시 데이터를 읽을때 변경된 데이터를 읽을 수 있음 (즉, 먼저 변경한 쪽의 데이터를 다시 읽게 됨)
  • Phantom read: 다른 트랜잭션이 신규 데이터를 추가하거나, 기존 데이터를 삭제할때, 범위 쿼리를 수행하면 데이터 row가 달라지는 현상.

격리수준이 낮은 것에서 높은 순서대로 알아보자.

READ_UNCOMMITTED


커밋하지 않은 데이터도 접근할 수 있다.
커밋되지 않아도 T2에서 A가 2로 읽히는 것을 볼 수 있다.
정합성은 떨어지지만, 성능은 좋다. 성능을 극대화해야 할때 사용.

READ_COMMITTED


커밋된 데이터만 조회할 수 있다.
Dirty Read가 발생하지 않는다.
커밋 후 T2에서 A를 다시 읽을 때 2로 읽히는 것을 볼 수 있다.

REPEATABLE_READ


트랜잭션 시작전에 스냅샷을 만들어서 사용함.
커밋전까지는 다시 읽어도 계속 같은 데이터를 얻게 됨

변경 전의 레코드를 언두 공간에 백업해둔다. 그러면 변경 전/후 데이터가 모두 존재하므로, 동일한 레코드에 대해 여러 버전의 데이터가 존재한다고 하여 이를 MVCC(Multi-Version Concurrency Control, 다중 버전 동시성 제어)라고 부른다

MVCC를 이용해 한 트랜잭션 내에서 동일한 결과를 보장하지만, 새로운 레코드가 추가되는 경우에 부정합이 생길 수 있다.

SELECT로 조회한 경우 트랜잭션이 끝나기 전에 다른 트랜잭션에 의해 추가된 레코드가 발견될 수 있는데, 이를 유령 읽기(Phantom Read)라고 한다. 하지만 MVCC 덕분에 일반적인 조회에서 유령 읽기(Phantom Read)는 발생하지 않는다. 왜냐하면 자신보다 나중에 실행된 트랜잭션이 추가한 레코드는 무시하면 되기 때문.

일반적으로 MySQL의 REAPEATABLE READ에서는 Phantom Read가 발생하지 않는다.
MySQL에서 Phantom Read가 발생하는 거의 유일한 케이스는 다음과 같다.
사용자 B는 트랜잭션을 시작하고, 잠금없는 SELECT 문으로 데이터를 조회하였다. 그리고 사용자 A는 INSERT 문을 사용해 데이터를 추가하였다. 이때 잠금이 없으므로 바로 COMMIT 된다. 하지만 사용자 B가 SELECT FOR UPDATE로 조회를 했다면, 언두 로그가 아닌 테이블로부터 레코드를 조회하므로 Phantom Read가 발생한다.

출처: https://mangkyu.tistory.com/299 [MangKyu's Diary:티스토리]

SERIALIZABLE

트랜잭션이 종료되어야 다음 트랜잭션 순차적 실행.
여러 트랜잭션이 동일한 레코드에 동시 접근할 수 없다.
극단적으로 안전해야하는 작업에서 사용

profile
윤성

0개의 댓글