0. 트랜잭션이란 ?
- 트랜잭션이란 DB의 상태를 변환시키는 논리적 단위나 일련의 연산을 말합니다.
- 하나의 트랜잭션은 반드시 Commit 되거나 Rollback 되어야 합니다.
트랜잭션의 성질 (ACID 특징)
- 원자성(Atomicity) : 트랜잭션 연산은 DB에 모두 반영되던지 혹은 전혀 반영되지 않아야 한다.
- 일관성(Consistency) : 트랜잭션 성공 후에는 일관성 있는 DB로 변한다.
- 독립성(Isolation) : 하나의 트랜잭션 실행에 다른 트랜잭션 연산이 끼어들 수 없다.
- 영속성(Durability) : 트랜잭션 성공 후에는 영구적으로 반영되어야 한다.
트랜잭션의 격리 수준
- 격리수준은 아래로 갈 수록 더 높아진다.
- READ UNCOMMITED : 아직 commit 되지 않은 데이터에 대해 다른 트랜잭션 읽기 허용
- 이 경우 Dirty read 문제가 발생할 수 있다. (데이터 불일치)
(트랜잭션 A가 수정하는 동안 트랜잭션 B가 읽은 후 트랜잭션 A의 오류로 롤백된다면,
B가 읽은 데이터는 유효한 데이터가 아니다)
- 이 경우 Dirty read 문제가 발생할 수 있다. (데이터 불일치)
- READ COMMITED : commit된 데이터에 대해서만 다른 트랜잭션 읽기 허용 (Dirty read 방지)
- 이 경우 Non-repeatable read 문제가 발생할 수 있다.
( 트랜잭션 A가 조회 도중 트랜잭션 B가 내용을 변경했을 시에,
트랜잭션 A가 다시 조회 한다면 B에 의해 변경된 데이터를 불러오게 된다. )
- 이 경우 Non-repeatable read 문제가 발생할 수 있다.
- REPEATABLE READ : 다른 트랜잭션이 데이터 읽고 있다면 다른 트랜잭션의 수정은 불가능한 읽기 전용 상태이다.
- 이 경우 Phantom read 문제가 발생할 수 있다.
( 회원 목록 조회(트랜잭션 A), 회원 가입 처리(트랜잭션 B)가 있을 때,
A가 계속해서 회원 수를 갖고오고 있을 때 B가 회원가입처리 한다면 A가 읽는 값이 달라지는 것이다.)
- 이 경우 Phantom read 문제가 발생할 수 있다.
- SERIALIZABLE : 하나의 트랜잭션이 읽는 것들은 모두 Shared Lock을 걸어서 다른 트랜잭션이 수정하지 못하게 함
- 가장 높은 격리 정책
- 성능 저하 우려
1. @Transactional 옵션
1-1. propagation (전파 속성)
- 트랜잭션에서 다른 트랜잭션 호출 시 어떠한 방식으로 처리할 지 설정하는 것
a. REQUIRED (기본값)
- 부모 트랜잭션이 있다면 거기에 참여
- 없다면 새로운 트랜잭션 생성
b. REQUIRES_NEW
- 부모 트랜잭션 무시, 항상 새로운 트랜잭션을 만든다,
- 기존 진행 중인 트랜잭션이 있다면 새로 만든 트랜잭션 먼저 처리하고 그 다음 처리한다.
c. MANDATORY
- REQUIRED와 비슷하게 이미 시작된 트랜잭션에 참여
- 이미 시작된 트랜잭션이 없다면 예외 발생 ( 독립적으로 실행하면 안 되는 트랜잭션만 사용 )
d. SUPPORTS
- 부모 트랜잭션이 있다면 그 트랜잭션에서 작업 수행
- 없다면 트랜잭션 없이 실행 (nonTransactionally)
e. NOT_SUPPORT
- 이미 진행 중인 트랜잭션이 있다면 실행 보류
- 트랜잭션 실행 끝나거나 실행 중인 트랜잭션이 없다면 트랜잭션 없이 바로 작업 실행
f. NEVER
- 트랜잭션을 사용하지 않도록 강제 설정
- 이미 실행 중인 트랜잭션이 있으면 Exception 발생
g. NESTED
- 이미 진행 중인 트랜잭션이 있다면 중첩으로 실행 (중첩 트랜잭션은 롤백 시 부모 트랜잭션에 영향 X)
- 존재하지 않으면 새로운 트랜잭션 만들어 실행
1-2. isolation (격리 레벨)
- DEFAULT / READ_UNCOMMITED / READ_COMMITED / REPEATABLE_READ / SERIALIZABLE (위에서 설명)
1-3. timeout
- 제한 시간을 정의하고 지정한 시간 초과한다면 실행 중단하고 롤백
- 기본 값은 -1 즉, 시간 제한이 없음
- 예시 ( @Transactional(timeout=5) )
1-4. readOnly
- 현재 트랜잭션이 읽기 전용인지 쓰기도 허용하는지 정의
- select의 경우 해당 설정 사용
1-5. rollbackFor 혹은 rollbackForClassName
- rollback 유발하는 예외 클래스 지정
- 예시( @Transactional(rollbackFor=Exception.class )
1-6. noRollbackFor 혹은 noRollbackForClassName
- 특정 예외가 발생하더라도 롤백되지 않도록 설정
- 예시 ( @Transactional(noRollbackFor=Exception.class)
2. Service Layer에서 @Transactional 에서 사용하는 이유
- 회사 또는 프로젝트마다 아키텍처가 다르며 하나의 비즈니스 로직에서 여러 개의 DAO를 호출할 수 있기 때문이다.
- 따라서, 특정 DAO 작업이 실패한다면 한꺼번에 롤백하기 위해 Service Layer에서 @Transactional을 붙인다.
[참고 링크] https://developer-talk.tistory.com/418
3. Transaction Rollback과 Exception 처리
- @Transactional Annotation은 Runtime Exception 혹은 Error 발생한 경우에만 Rollback 처리
- Checked Exception에는 Rollback 처리하지 않는다.
Exception의 종류
1) Runtime Exception : 프로그램 실행 중에 발생하는 개발자가 처리하기 어려운 예외
2) Checked Exception : 프로그램이 제어할 수 없지만 개발자가 충분히 처리 가능한 예외
3) Error : Exception이 아닌 경우, 시스템 메모리 부족 등의 처리 불가능한 에러
Checked Exception 에도 Rollback 처리
https://pjh3749.tistory.com/269
// 선언
@Transactional
// 위와 같다 ( 기본값 )
@Transactional(rollbackFor = {RuntimeException.class, Error.class})
// Checked Exception에 대해서도 rollback 진행
@Transactional(rollbackFor = {Exception.class})
스프링에서 Checked Exception 을 Rollback 처리 하지 않는 이유
- 기본적으로 Checked Exception 은 개발자가 처리 가능한 예외입니다.
- 따라서 스프링은 이는 개발자가 예외처리를 제대로 하지 않아서 발생했다고 여깁니다.
- 이는 가능한 경우 try .. catch로 받아서 처리합니다.
-. 확인질문
1. 트랜잭션이란 무엇인가요 ? 왜 사용하시나요 ?
2. 트랜잭션의 전파레벨에 대해서 설명해 주세요.
3. 트랜잭션의 격리 수준 레벨에 대해서 설명해 주세요.
4. Dirty Read란 무엇인가요 ?
- 트랜잭션이 완료되지 않은 상황에서 데이터 접근을 허용하는 경우 발생하는 문제
5. Non-Repeatable Read란 무엇인가요 ?
- 한 트랜잭션에서 같은 쿼리를 두 번 실행 시 발생하는 데이터 불일치
6. Phantom Read란 무엇인가요 ?
- 한 트랜잭션에서 일정 범위의 레코드를 두 번 읽었을 때 발생하는 데이터 불일치
참고
[1] [Spring] Transactional 정리 및 예제 - 갓대희
[2] JavaTransactional Annotation 알고 쓰자 - 26her30h
[3] [Spring] Transactional 어노테이션 사용 및 롤백 처리
'Spring' 카테고리의 다른 글
Spring Boot + Nuxt.js 환경에서의 FCM 웹 푸시 구현 (1/2) - Spring Boot편 (0) | 2023.04.15 |
---|---|
[Mybatis] Mybatis에서 DTO로 분리하기 (0) | 2023.03.16 |
빈 등록 어노테이션 @Configuration, @Component, @Bean에 대해서 (2) | 2022.08.27 |
세션 vs JWT (0) | 2022.06.21 |
Spring Boot Rest API 이메일 인증 (2) | 2021.11.10 |