목차
- 트랜잭션
- ACID 원칙
- 트랜잭션 전파
- 트랜잭션 격리 레벨
배운 내용
트랜잭션
- 여러개의 작업들을 하나의 그룹으로 묶어서 처리하는 처리 단위
**ACID 원칙**
1. 원자성(Atomicity)
- 작업을 더이상 쪼갤 수 없음을 의미
- 물리적으로는 여러 개의 작업이지만 논리적으로는 마치 하나의 작업으로 인식해서
전부 성공하든가 전부 실패하든가(All or Nothing) 중에서 하나로만 처리
2. 일관성(Consistency)
- 트랜잭션이 에러없이 성공적으로 종료될 경우, 비즈니스 로직에서 의도하는대로 일관성있게 저장되거나 변경되는 것
3. 격리성(Isolation)
- 여러 개의 트랜잭션이 실행될 경우 각각 독립적으로 실행이 되어야 함을 의미
- 데이터베이스는 한개 이상의 트랜잭션을 번갈아가면서 처리할 수 있는데, 이 경우 각 트랜잭션이 다른 트랜잭션에 영향을 주지 않고 독립적으로 실행이 되어야 한다
4. 지속성(Durability)
- 트랜잭션이 완료되면 그 결과는 지속되어야 한다
- DB가 종료되어 데이터는 물리적인 저장소에 저장되어 지속적으로 유지되어야 한다.
**커밋(commit)**
- 모든 작업을 최종적으로 데이터베이스에 반영하는 명령어
- 변경된 내용이 데이터베이스에 영구적으로 저장됨
- commit 명령을 수행하면, 하나의 트랜젝션 과정은 종료하게 된다.
**롤백(rollback)**
- 작업 중 문제가 발생했을 때, 트랜잭션 내에서 수행된 작업들을 취소한다.
- 트랜잭션 시작 이 전의 상태로 되돌아간다.
**선언형 방식의 트랜잭션 적용**
@Transactional
@Transactional
애너테이션을 클래스 레벨에 추가하면, 해당 클래스에서 MemberRepository의 기능을 이용하는 모든 메서드에 트랜잭션이 적용된다.
체크 예외 Rollback
Transactional
애너테이션만 추가해서는 rollback이 되지 않는다.
- → 캐치(catch)한 후에 해당 예외를 복구할지 회피할지 결정해야한다.
@Transactional(rollbackFor = {SQLException.class, DataFormatException.class})
와 같이 해당 체크 예외를 직접 지정해주거나 언체크 예외(unchecked exception)로 감싸서 rollback이 동작하도록 할 수있다.
클래스 레벨과 메서드 레벨의 트랜잭션 적용 순서
클래스 레벨에만 @Transactional
이 적용된 경우
- 클래스 레벨의
@Transactional
애너테이션이 메서드에 일괄 적용
클래스 레벨과 메서드 레벨에 함께 적용된 경우
- 메서드 레벨의
@Transactional
애너테이션이 적용
- 메서드 레벨에
@Transactional
애너테이션이 적용되지 않았을 경우, 클래스 레벨의 @Transactional
애너테이션이 적용
@Transactional(readOnly = true) 읽기 전용
@Transactional(readOnly = true)
로 설정하면 JPA 내부적으로 영속성 컨텍스트를 flush
하지 않는다.
- 읽기 전용 트랜잭션일 경우, 변경 감지를 위한 스냅샷 생성도 하지 않는다. → 불필요한 추가동작 줄일수 있다.(성능최적화)
- 조회 메서드에는 readonly 속성을 true로 지정해서 JPA가 자체적으로 성능 최적화 과정을 거치도록 하는것이 좋다.
트랜잭션 전파(Transaction Propagation)
- 트랜잭션의 경계에서 진행 중인 트랜잭션이 존재할 때 또는 존재하지 않을 때, 어떻게 동작할 것인지 결정하는 방식
propagation = Propagation.REQUIRED
- 디폴트 값, 현재 진행 중인 트랜잭션이 존재하면 해당 트랜잭션을 사용하고, 존재하지 않으면 새 트랜잭션을 생성
Propagation.REQUIRES_NEW
- 이미 진행중인 트랜잭션과 무관하게 새로운 트랜잭션이 시작
- 기존에 진행중이던 트랜잭션은 새로 시작된 트랜잭션이 종료할 때까지 중지된다.
Propagation.MANDATORY
Propagation.NOT_SUPPORTED
- 트랜잭션을 필요로 하지 않음을 의미
- 진행 중인 트랜잭션이 있으면 메서드 실행이 종료될 때 까지 진행중인 트랜잭션은 중지되며, 메서드 실행이 종료되면 트랜잭션을 계속 진행
Propagation.NEVER
- 트랜잭션을 필요로 하지 않음을 의미하며, 진행 중인 트랜잭션이 존재할 경우에는 예외를 발생
트랜잭션 격리 레벨(Isolation Level)
- 반적으로 데이터베이스나 데이터소스에 설정된 격리 레벨을 따르는 것이 권장
Isolation.DEFAULT
데이터베이스에서 제공하는 기본 값
Isolation.READ_UNCOMMITTED
다른 트랜잭션에서 커밋하지 않은 데이터를 읽는 것을 허용
Isolation.READ_COMMITTED
다른 트랜잭션에 의해 커밋된 데이터를 읽는 것을 허용
Isolation.REPEATABLE_READ
트랜잭션 내에서 한 번 조회한 데이터를 반복해서 조회해도 같은 데이터가 조회되도록 한다
Isolation.SERIALIZABLE
동일한 데이터에 대해서 동시에 두 개 이상의 트랜잭션이 수행되지 못하도록 한다.
**AOP 방식의 트랜잭션 적용**
- 대부분의 트랜잭션 적용은
@Transactional
애너테이션을 사용하는 방법만으로 간단하게 적용이 가능