728x90
반응형
하나의 Controller 메소드 안에서 Service를 여러 개 호출 할 때,
일부는 @Transactional 가 있고, 일부는 없으면 어떻게 될까?
각각 독립된 트랜잭션으로 동작해요!
Controller에 @Transactional이 없으면, 묶어줄 부모 트랜잭션이 없으니까 Service들이 각자 자기 트랜잭션을 생성하고 끝내요.
Controller (트랜잭션 없음)
│
├─→ ServiceA @Transactional → 트랜잭션 A 시작 → 커밋 ✅ (완전히 끝남)
│
├─→ ServiceB @Transactional → 트랜잭션 B 시작 → 커밋 ✅ (완전히 끝남)
│
└─→ ServiceC (없음) → 그냥 실행 (트랜잭션 없이)
문제가 생기는 상황
// Controller
public void controllerMethod() {
serviceA.save(); // @Transactional - 커밋 완료 ✅
serviceB.save(); // @Transactional - 커밋 완료 ✅
serviceC.doSomething(); // @Transactional 없음
// 💥 여기서 예외 발생!!
}
serviceA → 이미 커밋됨, 롤백 ❌ 불가
serviceB → 이미 커밋됨, 롤백 ❌ 불가
serviceC → 트랜잭션 없으니 롤백 개념 자체가 없음
→ 데이터 불일치 발생! 💀
해결책
이 세 개를 하나의 트랜잭션으로 묶고 싶으면 감싸는 Service를 만들어요.
// Controller
public void controllerMethod() {
wrapperService.doAll(); // 여기만 호출
}
// WrapperService (또는 기존 Service 중 하나에 합치기)
@Transactional // 얘가 트랜잭션 시작
public void doAll() {
serviceA.save(); // 같은 트랜잭션 참여
serviceB.save(); // 같은 트랜잭션 참여
serviceC.doSomething(); // 같은 트랜잭션 참여
// 여기서 예외나면 셋 다 롤백 ✅
}
핵심 정리
상황 동작
| Controller @Transactional O | 전부 하나로 묶임 |
| Controller @Transactional X | Service마다 각자 트랜잭션 |
| 중간에 예외 발생 | 이미 커밋된 건 롤백 불가 💀 |
여러 Service를 하나의 작업단위로 묶어야 한다면, 반드시 상위에 @Transactional이 있는 레이어가 하나 있어야 해요.
728x90
반응형
'백엔드개발' 카테고리의 다른 글
| 공공데이터포털 30 SERVICE KEY IS NOT REGISTERED ERROR (2) | 2025.01.14 |
|---|---|
| 맥북 터미널 이름 바꾸기 로컬 사용자 이름 호스트 네임 (0) | 2025.01.12 |
| Docker 설치하는 방법 공식문서 링크 영어 문서 보는 꿀팁 (1) | 2025.01.08 |
| 파이썬 mac 안에 가상환경 만들기 - virtualenv (1) | 2024.12.28 |
| Ubuntu Docker compose 도커컴포즈 설치 이유 설치 방법 (0) | 2024.11.09 |