해결된 질문
작성
·
127
·
수정됨
0
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.
1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오) 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예
[질문 내용]
트랜잭션 내부 호출관련하여 질문있습니다.
강의에서 언급해주신대로, 트랜잭션이 적용되지 않은 External()함수가 트랜잭션이 적용된 Internal() 함수를 내부 호출할 경우, Internal() 함수에 트랜잭션이 적용되지 않는 다는 것을 이해했습니다.
만약, 이 경우처럼 트랜잭션이 적용된 Login() 함수가 똑같이 트랜잭션이 적용된 getSocialInfo() 메서드를 호출할 경우에는, 어떻게 동작하는지 궁금합니다. 똑같이 내부 호출이기 때문에 무시되는지, 아니면 트랜잭션이 따로 적용되지만 전파 기본 옵션인 REQUIRED
에 따라 자동으로 같은 물리 트랜잭션으로 묶이는 방식으로 동작하는지 궁금합니다. 이 경우, getSocialInfo의 트랜잭션 전파 옵션을 NOT_SUPPORT
로 설정한다면 정상적으로 전파 옵션이 적용되는지도 궁금합니다.
답변 1
2
안녕하세요. constela10님
예를 들어, 아래처럼 동일 클래스 내에서 @Transactional
이 붙은 두 메서드가 있다고 해 봅시다.
@Service
public class AuthService {
@Transactional
public void login() {
// 로그인 로직
getSocialInfo(); // 내부 메서드 호출
}
@Transactional
public void getSocialInfo() {
// 소셜 로그인 정보 조회 로직
}
}
이때 login()
이 자기 내부에서 getSocialInfo()
를 직접 호출하면,
외부에서 login()
을 호출할 때만 스프링 프록시가 적용되어 트랜잭션이 시작됩니다.
내부에서 this.getSocialInfo()
를 부르는 순간에는 이미 프록시를 우회하기 때문에, getSocialInfo()
에 붙은 @Transactional
은 새로운 트랜잭션 경계를 만들지 못합니다.
하지만 여기서 주의해야 할 점이 있습니다. 트랜잭션이 ‘적용되지 않는다’(Annotation이 무시된다)는 것과, ‘트랜잭션 없이 동작한다’가 완전히 같은 말은 아닙니다. 이미 login()
메서드에서 트랜잭션이 시작되었으므로, 실제 DB와의 물리 트랜잭션(Connection)은 걸려 있는 상태입니다. 다만 getSocialInfo()
에 선언된 전파 옵션(Propagation 등)은 새로운 경계를 만들어낼 수 없을 뿐입니다. 결과적으로,
프록시 레벨에서는
getSocialInfo()
가 신규 트랜잭션/전파옵션을 가질 기회가 없음물리 DB 레벨에서는 이미
login()
이 시작한 같은 트랜잭션으로 묶여서 동작
정도로 이해하시면 됩니다.
감사합니다.