ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Boot 고급 시리즈 1편 – @Transactional 완전 정복: 실무 트랜잭션 설계 전략
    기술과 산업/언어 및 프레임워크 2025. 4. 17. 21:28
    728x90

    Spring Boot에서 @Transactional을 제대로 이해하고 사용하는 방법을 정리했습니다. 트랜잭션 전파, 롤백 전략, 예외 처리까지 실무 중심으로 설명합니다.


    Spring Boot 고급 시리즈 1편 – @Transactional 완전 정복: 실무 트랜잭션 설계 전략

    Spring Boot 개발에서 @Transactional은 마법처럼 보이지만, 그 이면을 제대로 이해하지 않으면 데이터 정합성 이슈롤백 실패라는 큰 문제에 직면할 수 있습니다.
    이번 글에서는 @Transactional의 내부 동작 원리부터 전파 속성, 예외 처리 전략, 그리고 테스트 설계까지 실무에서 반드시 알아야 할 트랜잭션 처리 방식을 깊이 있게 분석합니다.


    📌 1. @Transactional 기본 개념

    @Transactional
    public void createUser(UserDto dto) {
        userRepository.save(dto.toEntity());
    }
    
    • @Transactional은 메서드나 클래스에 선언 가능
    • 시작 시 트랜잭션을 열고, 종료 시 커밋 또는 롤백
    • 내부적으로는 **스프링 AOP(프록시 기반)**로 동작

    🔄 2. 트랜잭션 전파(Propagation) 완벽 이해

    전파 속성은 트랜잭션이 있는 상황에서 다른 트랜잭션을 호출할 때 어떻게 동작할지를 정의합니다.

    속성 설명

    REQUIRED 기본값, 기존 트랜잭션 있으면 참여, 없으면 새로 시작
    REQUIRES_NEW 항상 새로운 트랜잭션 시작, 기존 트랜잭션은 일시 중단
    NESTED 내부 트랜잭션, savepoint 지원 (DB가 지원해야 함)
    SUPPORTS 있으면 참여, 없으면 트랜잭션 없이 실행
    MANDATORY 반드시 기존 트랜잭션 있어야 실행, 없으면 예외
    NOT_SUPPORTED 트랜잭션 무시하고 실행
    NEVER 트랜잭션 존재 시 예외 발생

    ✅ 실무 팁

    • 이메일 전송, 로그 기록 등은 REQUIRES_NEW로 분리하면 실패해도 원 트랜잭션에 영향 없음
    • 동일 클래스 내부 호출은 AOP 적용되지 않아 전파 속성 무시됨 → 분리된 Bean으로 구성 필요

    🧨 3. 트랜잭션 롤백 규칙

    기본적으로는 Unchecked Exception(RuntimeException, Error) 발생 시 롤백됩니다.

    @Transactional
    public void save() {
        throw new RuntimeException("예외 발생"); // 롤백됨
    }
    

    ⚠️ Checked Exception 처리

    @Transactional(rollbackFor = SQLException.class)
    public void save() throws SQLException {
        throw new SQLException(); // rollbackFor 없으면 커밋됨
    }
    
    • rollbackFor, noRollbackFor로 롤백 정책 명시
    • 예외 타입에 따라 롤백 여부가 결정된다는 점을 항상 고려해야 합니다.

    🧠 4. 실무 트랜잭션 설계 전략

    🔷 트랜잭션은 "서비스 계층"에서만 선언

    • Repository 계층에는 선언하지 않음 → 단순 DB 호출 역할만 수행
    • Service는 “업무 단위”를 정의 → 트랜잭션도 이 단위에 묶이는 것이 자연스러움

    🔷 외부 호출 전후는 트랜잭션 분리

    • 외부 API 호출, 메일 전송, 파일 업로드 등은 실패 가능성이 높음
    • 메인 트랜잭션과 분리 → REQUIRES_NEW 또는 트랜잭션 없이 실행

    🔷 복합 트랜잭션은 메서드 분리 & 명확한 책임 분산

    public void registerUser() {
        saveUser();           // DB 저장 트랜잭션
        sendWelcomeEmail();   // 별도 트랜잭션 or 비동기 처리
    }
    

    🧪 5. @Transactional 테스트 전략

    ✅ 테스트용 트랜잭션 자동 롤백

    @SpringBootTest
    @Transactional
    class UserServiceTest {
        // 테스트 종료 시 자동 롤백
    }
    

    ✅ 트랜잭션 테스트 주의사항

    • 동일 트랜잭션 내에서 쿼리 실행 시 영속성 컨텍스트에 의해 반영됨
    • DB에 실제 반영되는지 확인하려면 flush() 또는 @Rollback(false) 활용

    ✅ 마무리 요약

    항목 핵심 포인트

    선언 위치 Service 계층 권장
    전파 속성 REQUIRED, REQUIRES_NEW 필수 이해
    롤백 조건 기본 RuntimeException, Checked 예외는 명시 필요
    내부 호출 AOP 적용되지 않음 → 분리된 빈에서 호출
    테스트 전략 자동 롤백, @Rollback 옵션 설정 가능

    📌 다음 편 예고

    Spring Boot 고급 시리즈 2편: 계층 분리와 서비스 아키텍처 – 유지보수 가능한 구조 만들기

     

     

    728x90
Designed by Tistory.