-
Spring Boot 고급 시리즈 1편 – @Transactional 완전 정복: 실무 트랜잭션 설계 전략기술과 산업/언어 및 프레임워크 2025. 4. 17. 21:28728x90
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'기술과 산업 > 언어 및 프레임워크' 카테고리의 다른 글
Spring Boot 고급 시리즈 3편 – 커스텀 예외와 오류 코드 설계 전략 (0) 2025.04.18 Spring Boot 고급 시리즈 2편 – 유지보수 가능한 서비스 아키텍처 설계 전략 (0) 2025.04.18 Spring Boot 시리즈 5편 – API 응답 구조 표준화 전략: 일관된 성공/실패 응답 설계하기 (0) 2025.04.17 Spring Boot 시리즈 4편 – @Valid 입력값 검증과 글로벌 예외 처리 전략 (0) 2025.04.17 Spring Boot 시리즈 3편 – JPA로 DB 연동하기: Entity와 Repository 설계 전략 (0) 2025.04.16