본문 바로가기
JPA

JPA - 트랜잭션 매니저2 독립성(격리) 속성

by sinabeuro 2022. 3. 25.
728x90

 

@Transaction 속성

@Transaction 에 설정할 수 있는 속성은 다음과 같습니다.

http://wiki.gurubee.net/pages/viewpage.action?pageId=26741432 참조

@Transaction 속성 중에 이번 포스트에서 isolation 속성을 살펴보겠습니다.

 

 

 

Isolation 속성

Isolation 은 트랜잭션에서 독립성 혹은 격리성이라고 부릅니다.

Isolation 은 Transaction 에서 일관성이 없는 데이터를 허용하도록 하는 수준이며, 여러 Transaction들이 다른 Transaction의 방해로부터 보호되는 정도를 나타냅니다.

 

격리성에는 격리 레벨(수준)이 존재합니다.

격리 레벨이 높은 수록 데이터의 정합성을 보장해주는 대신에 동시 처리하는 수행능력(성능)이 떨어지게 됩니다.

반대로, 격리 레벨이 낮을 수록 성능은 좋아지지만 데이터의 정합성이 떨어지게 됩니다.

격리 레벨은 다음과 같습니다. ISOLATION_DEFAULT 를 제외하고 아래로 갈수록 격리 레벨이 높아집니다.

http://wiki.gurubee.net/pages/viewpage.action?pageId=26741432 참조

사용 방법은 

@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Transactional(isolation = Isolation.REPEATABLE_READ)
@Transactional(isolation = Isolation.SERIALIZABLE)

와 같은 방법으로 @Transactional 어노테이션에서 isolation 속성을 지정하면 됩니다.

 

격리 레벨을 하나씩 살펴보겠습니다.

 

DEFAULT

데이터베이스에 지정된 격리 레벨을 사용합니다. 

격리 레벨에 아무 것도 지정하지 않으면 디폴트로 적용됩니다.

참고로 MySQL 데이터베이스의 기본 격리 수준은 REPEATABLE_READ 입니다.

PostgresSQL 데이터베이스의 기본 격리 수준은 READ_COMMITTED 입니다.

Oracle 데이터베이스의 기본 격리 수준은 READ_COMMITTED 입니다.

 

데이터 베이스의 격리 수준은 언제든 변경/확인 가능합니다.

데이터 베이스에 따라 격리 수준이 다르기 때문에 사용하시는 데이터 베이스의 격리 수준을 알아두는 것도 좋을 것 같습니다.

 

 

READ_UNCOMMITTED

레벨0, 다른 트랜잭션 수행에 커밋되지 않은 결과를 조회할 수 있습니다.

해당 수준에서 커밋되지 않는 변경한 데이터를 조회하는 문제가 발생합니다.

이러한 현상을 더티 리드(Dirty Read)라고 합니다.

(해당 수준에서 데이터 정합성에 문제가 많으므로, RDBMS 표준에서는 격리수준으로 인정하지도 않는다고 합니다.)

 

 

READ_COMMITTED

레벨1, 다른 트랜잭션에서 커밋된 결과를 조회합니다. (Unrepeatable 상태)

해당 수준에서는 더티 리드 현상이 발생하지는 않지만, 그래도 데이터 부정합이 발생합니다.

 

트랜잭션 내에서 동일한 데이터를 두 번 이상 읽을 때, 다른 트랜잭션이 커밋한 결과를 볼 수 있습니다. 
다시 말해, 트랜잭션이 진행 중일 때 다른 트랜잭션에서 변경한 데이터를 볼 수 있습니다. 
이는 "Unrepeatable Read" 문제를 발생시킬 수 있습니다.

 

 

REPEATABLE_READ

트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회할 수 있는 격리수준입니다.

MySQL DBMS에서 기본으로 사용하고 있고, 이 격리수준에서는 NON-REPETABLE READ 부정합이 발생하지 않습니다.

트랜잭션마다 트랜잭션 ID를 부여하여 트랜잭션 ID보다 작은 트랜잭션 번호에서 변경한 것만 읽습니다.

 

다시말하면, 트랜잭션이 진행 중일 때 다른 트랜잭션이 해당 데이터를 변경하더라도, 트랜잭션 내에서 처음 읽은 시점의 데이터를 계속해서 보게 됩니다. 이는 "Non-Repeatable Read" 문제를 방지합니다.

 

하지만, 현재 트랜잭션이 실행 중일 때 다른 트랜잭션이 동시에 실행되는 도중에 Insert/Update/Delete 를 실행하면, 현재 트랜잭션에서 부정합이 발생합니다. 트랜잭션이 진행되는 동안 다른 트랜잭션이 행을 추가하거나 삭제하여 새로운 레코드가 발생하여, 두 번째 데이터 조회에서 새로운 레코드가 조회될 수 있는 것입니다.

이는 현재 트랜잭션이 실행이 끝나기 전에 다른 트랜잭션에서 변경한 데이터를 읽게 되므로 발생하는 문제입니다.

Phantom Read 현상
한 트랜잭션 내에서 같은 쿼리를 두 번 실행했는데, 
첫 번째 쿼리에서 없던 유령(Phantom) 레코드가 두 번째 쿼리에서 나타나는 현상을 말한다.

이러한 Phantom Read 현상을 방지하기 위해서는 다른 트랜잭션에서 쓰기 잠금을 걸어야합니다.

 

 

SERIALIZABLE

가장 단순한 격리 수준이지만 가장 엄격한 격리이며, 수준 성능 측면에서는 동시 처리성능이 가장 낮습니다.

읽기 작업에도 공유 잠금을 설정하게 되고, 이러면 동시에 다른 트랜잭션에서 이 레코드를 변경하지 못하게 됩니다.

이러한 특성 때문에 동시처리 능력이 다른 격리수준보다 떨어지고, 성능저하가 발생하게 됩니다.

SERIALIZABLE 격리 수준에서는 Phantom Read가 발생하지 않습니다.

하지만 성능상의 문제로 데이터베이스에서 거의 사용하지 않습니다.

 

 

 

 

 

참고자료

https://milenote.tistory.com/108

 

[ JPA ] 6-4. 트랜잭션 매니저 (TransactionManager)

Reference. 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online 이전 글 더보기 더보기 1. Repository interface 메서드 - 1 2. Query Method 정의 및 실습 - 2 3. Entity 기본 속성 - 3 4. Entity..

milenote.tistory.com

 

http://wiki.gurubee.net/pages/viewpage.action?pageId=26741432 

 

Transactional 어노테이션을 이용한 선언적 트랜잭션 - [종료]구루비 Dev 스터디 - 개발자, DBA가 함께

 

wiki.gurubee.net

 

https://joont92.github.io/db/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC-%EC%88%98%EC%A4%80-isolation-level/

 

[db] 트랜잭션 격리 수준(isolation level)

트랜잭션 격리수준(isolation level)이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다. 즉, 간단하게 말해 특정 트랜잭션이 다른 트랜잭션에

joont92.github.io

 

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

 

트랜잭션의 격리 수준(isolation Level)이란?

 

nesoy.github.io

 

728x90

'JPA' 카테고리의 다른 글

JPA - 트랜잭션 매니저3 전파 속성  (0) 2022.03.25
JPA - 트랜잭션 매니저1 개요  (0) 2022.03.25
JPA - Entity Listener  (0) 2022.03.25
JPA - 연관 관계  (0) 2022.03.25
JPA - Entity의 기본 속성  (0) 2021.12.03

댓글