작성
·
38
0
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.
1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)
[질문 내용]
여기에 질문 내용을 남겨주세요.
안녕하세요 김영한님 !
REQUIRES_NEW는 완전히 물리적으로 트랜잭션이 분리되어
REQUIRED(A 메서드)에서 REQUIRES_NEW(B 메서드)를
호출 했을 때 B 메서드에 발생한 예외가 A 메서드에 전파되지 않는다고 이해했습니다.
실제 확인을 위해 아래 코드를 구성해
@Service
@RequiredArgsConstructor
public class MeetingService {
private final MeetingRepository meetingRepository;
private final MemberService memberService;
@Transactional
public void save() {
meetingRepository.save(new Meeting("스터디 모임", LocalDate.now(), LocalTime.now(), "AB3AS2EG"));
memberService.save();
}
@Transactional(readOnly = true)
public List<Meeting> findAll() {
return meetingRepository.findAll();
}
}
@Service
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save() {
memberRepository.save(new Member("김철수"));
throw new IllegalArgumentException();
}
@Transactional(readOnly = true)
public List<Member> findAll() {
return memberRepository.findAll();
}
}
아래 테스트 코드로 테스트를 진행했습니다.
@Test
void test() {
assertThatThrownBy(() -> meetingService.save())
.isInstanceOf(IllegalArgumentException.class);
// 롤백 여부 확인
List<Meeting> meetings = meetingService.findAll();
List<Member> members = memberService2.findAll();
assertThat(meetings).isEmpty();
assertThat(members).isEmpty();
}
결과를 로그로 분석해보니
MemberService의 트랜잭션은 독립적으로 롤백
발생한 예외가 MeetingService로 전파
전파된 예외로 인해 MeetingService의 트랜잭션도 롤백
이런식으로 흐름이 진행됐습니다.
제가 추측하기로는 물리적으로 분리는 되어 있지만 하나의 스레드에서 생긴 커넥션이고 자바의 예외 전파 메커니즘에 따라
A 메서드에서 호출한 B 메서드의 예외가 A 메서드에 전파된 것이 아닌가 생각을 했는데요
REQUIRES_NEW 사용 시 예외가 전파 되지 않는다. 라고 이해를 했어서
제가 실험한 결과가 맞는지 간과한 부분이 있었던 것인지 궁금합니다 !
답변 2
0
안녕하세요. HH님
MeetingService에 있는 save()에서 예외를 잡아서 처리하지 않았습니다.
이 경우 MeetingService도 문제가 발생했다고 인지하고 트랜잭션을 롤백합니다.
MeetingService에 있는 save()에서 예외를 잡아서 처리해보세요 🙂
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다. HH님께서 질문하신 내용에 대한 이해를 돕기 위해 REQUIRES_NEW와 관련된 트랜잭션 전파에 대해 다양한 관점을 제공하겠습니다.
REQUIRES_NEW 전파 옵션은 기존 트랜잭션이 있더라도 새로운 트랜잭션을 생성하며, 이로 인해 해당 트랜잭션이 독립적으로 작동하게 됩니다. 이 때문에 보통 내부 트랜잭션(B 메서드)에서 예외가 발생해 롤백되더라도 외부 트랜잭션(A 메서드)에는 직접적인 영향을 주지 않는다고 인식됩니다.
하지만, 질문하신 코드와 테스트 결과에서 IllegalArgumentException
이 메서드 호출을 통해 전파되면서 외부 트랜잭션(A 메서드)도 롤백되는 결과가 나타났습니다. 이 상황은 자바의 예외 전파 메커니즘 때문입니다. 메서드 호출 시 예외가 발생하면 그 예외는 호출자에게 전파되며, 예외로 인해 호출한 메서드가 롤백될 수 있습니다. 따라서 예외 관리(catch 블록 활용 등) 및 처리가 필요합니다.
관련된 질문을 참고하실 수 있는 페이지를 추천해 드립니다:
- 내부 트랜잭션 REQUIRES_NEW 질문입니다. - REQUIRES_NEW 사용 시의 커넥션풀 관리와 관련된 논의가 이루어졌습니다.
- spring Exception REQUIRES_NEW 질문 드립니다 - REQUIRES_NEW 사용 시 예외 발생 상황에 대한 논의가 포함되어 있습니다.
이 외에도 예외 전파 및 관리에 대한 부분을 좀 더 깊이 이해하기 위해 Spring의 트랜잭션 관리와 예외 처리 패턴에 대한 추가 학습을 추천드립니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
참고로 주신 질문 게시글들은 저의 질문과 관련이 없는 것 같습니다!
제가 이해한바가 맞다면 강의에서 설명한 REQUIRES_NEW로 분리한 트랜잭션을 호출한 메서드에 롤백이 일어나지 않는 상황은 다른 상황일까요?
제가 강의를 제대로 보지 못했었던것 같네요 ..!
예외는 전파되지만 트랜잭션을 분리하면 분리된 트랜잭션의 예외를 따로 잡아 핸들링할 수 있는 것이였네요 답변 감사합니다 !