📍 하나의 트랜잭션 안에서 다른 트랜잭션을 어떻게 처리할지 결정하는 옵션
쉽게 말해:
메서드 A가 트랜잭션을 시작했는데,
그 안에서 또 다른 메서드 B를 호출할 때,
B도 @Transactional이면,
👉 그 트랜잭션을 어떻게 이어갈지 정하는 게 propagation이다
REQUIRED 가 기본적으로 적용된다. (DEFAULT)
@Transactional 어노테이션은 하위 메서드까지 롤백될 수 있다. (DEFAULT 적용되기 때문)
예를 들면,
회원가입 메서드 & 포인트 적립 메서드가 함께 @Transactional 안에 묶여있는 경우
포인트 적립에만 문제가 생겨도 롤백 → 회원가입도 되지 않는 문제 발생
REQUIRED_NEW 속성을 사용하여 해결 가능
propagation 속성 :
1️⃣ REQUIRED(Default)
2️⃣ REQUIRES_NEW
3️⃣ SUPPORTS
4️⃣ NOT_SUPPORTED
5️⃣ MANDATORY
6️⃣ NEVER
7️⃣ NESTED
| propagation 종류 | 설명 |
|---|---|
REQUIRED (기본값) | 기존 트랜잭션이 있으면 같이 사용, 없으면 새로 시작 |
REQUIRES_NEW | 무조건 새 트랜잭션 시작, 기존 건 잠시 보류 |
NESTED | 기존 트랜잭션 안에 중첩 트랜잭션 시작 (롤백 독립적으로 가능) |
SUPPORTS | 트랜잭션 있으면 사용, 없으면 그냥 비트랜잭션으로 실행 |
NOT_SUPPORTED | 트랜잭션 있으면 일시 중단, 트랜잭션 없이 실행 |
MANDATORY | 무조건 기존 트랜잭션이 있어야 함, 없으면 예외 |
NEVER | 트랜잭션 있으면 예외 발생 (절대 트랜잭션 안 씀) |
➡️ 상황마다 필요한 것을 골라서 사용하면 된다
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveLog() {
// 무조건 새로운 트랜잭션에서 실행
}
예를 들어, A 메서드가 DB에 회원 저장하고,
B 메서드는 이메일 전송 로그를 저장한다고 해봐.
B가 실패했을 때 A의 회원 정보까지 롤백되면 안 되니까,B는 REQUIRES_NEW로 분리하는 게 좋아!| 용도 | 설명 |
|---|---|
propagation | 트랜잭션 중첩/새로 만들기 여부를 설정 |
| 기본값 | REQUIRED (같은 트랜잭션 이어서 씀) |
| 자주 쓰는 것 | REQUIRED, REQUIRES_NEW, NESTED |
📍 추가 공부
오호 정리를 되게 잘하셨네요! 잘 보고 갑니다