728x90
반응형
🧐 트랜잭션이란 ?
DB 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들
🧐 JPA 트랜잭션 격리수준
트랜잭션이 보장해야하는 ACID 중 격리성과 관련된 내용인데 격리성을 완벽히 보장하려면 동시성 처리 성능이 매우 나빠진다.
이런 문제로 인해 ANSI 표준은 트랜잭션의 격리 수준을 4단계로 나누어 정의했다.
- Atomicity; 원자성
- 트랜잭션 내의 작업들은 모두 성공 또는 모두 실패한다.
- Consistency; 일관성
- 모든 트랜잭션은 일관성 있는 DB 상태를 유지한다.
- (ex: DB의 무결성 제약 조건 항상 만족)
- Isolation; 격리성
- 동시에 실행되는 트랜잭션들은 서로 영향을 미치지 않는다.
- (ex: 동시에 같은 데이터 수정 X)
- Durability; 지속성
- 트랜잭션이 성공적으로 끝나면 그 결과는 항상 기록되어야 한다.
🧐 트랜잭션 관리 포인트 3
낮은 단계의 트랜잭션 고립화 수준 이용시 발생하는 현상 3가지
- Nonrepeatble Read
- 트랜잭션이 수행중인데 다른 트랜잭션이 읽고 있는 데이터를 수정해서 쿼리 결과가 달라지는 것.
- 한 트랜잭션 내에서 같은 쿼리를 두 번 수행할 때
그 사이에 다른 트랜잭션이 값을 수정 또는 삭제함으로써
두 쿼리의 결과가 상이하게 나타나는 비 일관성 발생한다.
- Phantom Read
- 동일한 쿼리가 다른 값을 반환하는 것
- 한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽을 때,
첫 번째 쿼리에서 없던 레코드가 두 번째 쿼리에서 나타나는 현상.
이는 트랜잭션 도중 새로운 레코드가 삽입되는 것을 허용하기 때문에 나타난다.
- Dirty Read
- 변경된 데이터가 아직 미완성인데 다른 트랜잭션에서 읽어가는 것.
- T1 트랜잭션에서 읽기하고 실행이 끝나지 않은 상태에서
T2 트랜잭션에 의해 변경된 사항을 보게 되는 경우를 dirty read 라고 한다.
만약 T2 트랜잭션에서 그 변경 사항을 rollback하면
그 데이터를 읽은 T1 트랜잭션은 Dirty 데이터를 가지고 있는 것이다.
🧐 격리수준
아래로 내려 갈수록 동시성이 높아지는 대신 속도가 느려진다. ( lv.0 -> lv.3)
위로 올라 갈수록 동시성이 떨어지는 대신 속도가 빨라진다. (lv.3 -> lv.0)
- READ UNCOMMITED (lv.0)
- 커밋되지 않은 데이터도 읽을 수 있음
- A트랜잭션에서 데이터를 변경하려다 에러가 발생해서 Rollback을 했다고 치면 A트랜잭션이 실행되는 동안 데이터를 요청한 B 트랜잭션은 잘못된 데이터를 읽고 있을 수가 있다. Dirty Read, Dirty Write이 가능함
- Dirty Read는 방지 X, Noorepeatable read방지 X, Phantom Read 방지 X
- 커밋되지 않은 데이터도 읽을 수 있음
- READ COMMITED (lv.1)
- 커밋된 데이터만 불러온다. (= 반복해서 같은 데이터를 불러올 수 없다)
- SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock(읽기 가능, 변경 불가)이 걸리는 레벨
- 어떠한 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 해당 데이터(B)에 접근할 수 없습니다.
- Dirty Read 방지 O , Non-Repeatable Read 방지 X
- SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock(읽기 가능, 변경 불가)이 걸리는 레벨
- 커밋된 데이터만 불러온다. (= 반복해서 같은 데이터를 불러올 수 없다)
- REPEATABLE READ (lv.2)
- 트랜잭션 동안에는 한번 조회한 데이터를 계속 조회해도 같은 데이터가 나오지만, 만약 다른 트랜잭션에서 데이터를 추가한 경우 기존 트랜잭션에서 반복 조회하면 결과 집합이 새로 추가된 데이터를 포함한 결과를 가져오게 된다.
- Dirty Read 방지 O, Non-Repeatable Read 방지 O, Phantom Read 방지 X
- 트랜잭션 동안에는 한번 조회한 데이터를 계속 조회해도 같은 데이터가 나오지만, 만약 다른 트랜잭션에서 데이터를 추가한 경우 기존 트랜잭션에서 반복 조회하면 결과 집합이 새로 추가된 데이터를 포함한 결과를 가져오게 된다.
- SERIALIZABLE (lv.3)
- 모든 트랜잭션을 순서대로 실행한다.
- Dirty Read 방지 O, Non-Repeatable Read 방지 O, Phantom Read 방지 O
JPA를 사용하면 격리 수준을 READ_COMMITED로 가정하는데
만약 일부 로직에 더 높은 격리 수준이 필요하면 비관적 락과 낙관적 락 중에 선택을 하여 사용해야 한다.
JPA의 추천하는 전략은 READ_COMMITTED + 낙관적 락 이다.
- 낙관적 락
- 트랜잭션 대부분은 충돌이 발생하지 않는 다고 가정하며, JPA가 제공하는 버전 관리 기능을 사용한다. (어플리케이션 단 레벨)
- 트랜잭션을 커밋하기 전까지는 트랜잭션의 충돌을 알 수 없다는 특징이 있다.
- JPA에서 제공하는 @Version 어노테이션을 사용하며, 최초 커밋만 인정되어 두번째 커밋에선 예외를 발생시킨다.
- 비관적 락
- 트랜잭션 간 충돌이 발생한다고 가정하여 우선 락을 건다, 데이터베이스가 제공하는 락 기능을 사용한다.
- 데이터를 수정하는 즉시 트랜잭션 충돌을 감지하며 예외를 발생시킨다.
- 비관적 락을 사용하면 락을 획득할 때까지 트랜잭션이 대기한다. 무한정 기다릴 수 없으므로 타임아웃 시간을 줄 수 있다.
JPA의 추천하는 전략은 READ_COMMITTED + 낙관적 락 이다.
728x90
반응형
'개발중 > Java Persistence API (JPA)' 카테고리의 다른 글
[JPA] 다른 컬럼명을 참조하는 연관관계에 대한 궁굼점 (referencedColumnName) (0) | 2023.02.13 |
---|---|
Criteria API 에 대해 알아보기 (0) | 2023.01.27 |
JPA ( Java Persistence API ) (0) | 2023.01.10 |
[Spring] JPA Specification 를 이용해 검색 API 개발하기 ✍ (0) | 2022.12.05 |
[JPA] JPA 의 장점이 뭔지 물어봤을 때 잘 대답하지 못했다. . . (1) | 2022.09.23 |