이번 주제도 cs 공부를 하다가 나온 주제다.
일반적으로 한 트랜잭션에 하나의 영속성 컨텍스트가 할당된다.
즉 A라는 트랜잭션 서비스에서 user를 찾으면 user를 영속성 컨텍스트에 저장.
그런데 여기서 나온 궁금증이
"만약 A서비스에서 B트랜잭션 서비스를 호출하고 user를 조회하면, A의 영속성 컨텍스트를 이용하나?"
이게 물음이었다.
테스트를 위해 간단한 서비스를 만들었다.
@Override
@Transactional
public void findUser(Long id) {
// 첫번째 트랜잭션에서 유저 조회
log.info("서비스1");
User user = userRepository.findById(id).get();
emailService.findUserUser(id);
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
@Override
@Transactional
public void findUserUser(Long id) {
// 여기서 조회를 하면 영속성 컨텍스트의 user를 찾을까? 아니면 새롭게 쿼리를 날릴까?
log.info("서비스2");
User user = userRepository.findById(id).get();
}
findUser에서 user를 조회하고, findUserUser를 불러서 동일한 유저를 조회한다.
만약에 같은 영속성 컨텍스트를 이용한다면? select쿼리는 한 번만 나갈 것이다.
하나의 조회 쿼리만 나간 걸 확인할 수 있다.
결론 : 트랜잭션에서 트랜잭션을 가면 같은 영속성 컨텍스트를 공유한다.
그런데 트랜잭션에서 전파 옵션을 설정할 수 있다.
일단 아무 옵션도 설정하지 않으면 REQUIRED로 잡힌다. 외부의 트랜잭션을 공유하는 상태가 된다.
그러므로 영속성 컨텍스트로 findUser의 것을 동일하게 사용하게 된다.
반면에 REQUIRES_NEW를 사용하면 별개의 트랜잭션으로 동작하기에, 영속성 컨텍스트를 공유하지 않는다.
@Override
@Transactional(Transactional.TxType.REQUIRES_NEW)
public void findUser(Long id) {
// 첫번째 트랜잭션에서 유저 조회
log.info("서비스1");
User user = userRepository.findById(id).get();
findUserUser(id);
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void findUserUser(Long id) {
// 여기서 조회를 하면 영속성 컨텍스트의 user를 찾을까? 아니면 새롭게 쿼리를 날릴까?
log.info("서비스2");
User user = userRepository.findById(id).get();
apiRequestService.findUserUserUser(id);
}
그래서 해당 코드를 실행하면
별개의 영속성 컨텍스트로 동작하는 것을 확인할 수 있었다.
반응형
'기타' 카테고리의 다른 글
SSAFY를 수료하고 7개월만에 취업 (취준 1년 7개월) (7) | 2024.07.24 |
---|---|
Openai에서 발표했던 GPT-4o에 대한 간단한 소감 (0) | 2024.05.14 |
GenerationType.IDENTITY는 정말로 쓰기 지연이 안 먹힐까? (0) | 2024.03.25 |
어떻게 HTTP는 로그인된 상태를 판단할까? (0) | 2024.02.07 |