[Spring] 트랜잭션 전파

이연우·2025년 8월 19일

TIL

목록 보기
90/100

🚦 트랜잭션 전파란?

  • 여러 계층/메서드가 서로 호출될 때,
    트랜잭션을 어떻게 이어갈지(또는 끊을지) 결정하는 규칙

  • 즉, "현재 트랜잭션과 다른 트랜잭션을 어떻게 교통정리할 것인가?"
  • @Transactional(propagation = …) 속성으로 지정

🧩 기본 동작 (REQUIRED – Default)

@Transactional
public void signUp(Member member) {
    memberRepository.save(member); // 회원 저장
    pointPolicy.addPoints(member.getId(), 100); // 포인트 지급
}
  • signUp() 에 트랜잭션 시작 → addPoints()도 같은 트랜잭션 사용
  • 포인트 지급 실패 시 → 회원 가입도 롤백됨

🚀 트랜잭션 동작

👉 한 묶음으로 처리하고 싶을 때 사용

🔄 트랜잭션 전파 종류

속성설명사용 예시
REQUIRED (Default) 🧵- 트랜잭션 있으면 참여
- 없으면 새로 시작
대부분의 서비스 로직
REQUIRES_NEW- 무조건 새 트랜잭션 시작
- 기존 트랜잭션은 잠시 보류
"포인트 지급 실패해도 회원가입은 성공해야 함" 같은 경우
SUPPORTS 🤝- 트랜잭션 있으면 참여
- 없으면 그냥 비트랜잭션으로 실행
읽기 전용 조회
NOT_SUPPORTED 🚫- 트랜잭션 중단 후 비트랜잭션 실행로그 저장, 모니터링
MANDATORY 📌- 반드시 기존 트랜잭션 필요
- 없으면 예외 발생
트랜잭션 강제해야 하는 핵심 로직
NEVER- 트랜잭션 없이 실행
- 있으면 예외 발생
트랜잭션 쓰면 안 되는 경우 (예: 캐시 로직)
NESTED 📂- 현재 트랜잭션 안에서 중첩 트랜잭션 생성
- 내부만 따로 롤백 가능
큰 트랜잭션 안에서 부분적으로 롤백 필요할 때

💡 예시 – REQUIRES_NEW

@Service
public class MemberService {
    @Transactional
    public void signUp(Member member) {
        memberRepository.save(member);
        pointPolicy.addPoints(member.getId(), 100); // 포인트 지급
    }
}

@Component
public class PointPolicy {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addPoints(Long memberId, int points) {
        pointRepository.save(new Point(memberId, points));
    }
}
  • 회원 가입 트랜잭션포인트 지급 트랜잭션 분리
  • 포인트 지급 실패해도 회원 가입은 롤백되지 않음 🙆

🚀 트랜잭션 동작


👉 쉽게 기억하기:

  • REQUIRED → 같이 묶어서 🚶‍♂️🚶‍♀️
  • REQUIRES_NEW → 따로 간다 ✈️
  • SUPPORTS → 있으면 같이, 없으면 그냥 🤷
  • NESTED → 안에 하나 더 📂

0개의 댓글