게시글
질문&답변
2021.10.06
@Transaction 전파 관련 문의
답변해주셔서 감사드립니다! osiv를 참고하여 on/off 조건으로 다음과 같이 테스트 결과를 정리해보았습니다. 추가 질문은 맨 마지막에 작성하였습니다. @RequiredArgsConstructor@Componentpublic class TestComponent { private final MemberRepository memberRepository; private final EntityManager em; @Transactional(propagation = Propagation.REQUIRES_NEW) public void capsule(Long id) { Member member2 = em.find(Member.class, id); System.out.println("member2 = " + member2); }} @GetMapping("/em/{id}")// @Transactional public void findMember5(@PathVariable("id") Long id) { Member member1 = memberRepository.findById(id).get(); System.out.println("member1 : " + member1); testComponent.capsule(id); } requires_new로 적용 > 1) osiv on(영속상태 유지(단, 수정 불가능). 즉 트랜잭션 범위 외에서도 영속 상태 유지 o) 조건 1 : 외부 메서드에 @Transactional 유 -> 다른 member 조회 조건 2 : 외부 메서드에 @Transactional 무 -> 같은 member 조회 2) osiv off(트랜잭션 종료 시 영속성 컨텍스트를 닫는다. 즉 트랜잭션 범위 밖에서는 영속상태 유지 x) 조건 3 : 외부 메서드에 @Transactional 유 -> 다른 member 조회 조건 4 : 외부 메서드에 @Transactional 무 -> 다른 member 조회 조건 1, 3의 경우 osiv on/off 여부에 상관 없이 외부에 @Transactional이 있기 때문에 컨트롤러 메서드 레벨에서 transaction이 시작되며, 내부의 requires_new가 잘 동작하여 각각 다른 member가 조회됩니다. 조건 2,4의 경우 osiv on/off 여부에 따라 member 조회 결과에 차이를 보이게 됩니다. 조건 4(osiv off)는 외부 메서드 내의 "repository.findById" 부분이 끝나자마자 영속성이 사라지게 되므로, 내부 메서드의 transaction이 완벽하게 분리가 되어 원하는대로 동작함을 확인했습니다.(내부 @transactional을 default로 설정해도 동일하게 동작) 조건 2(osiv on)는 외부 메서드 내의 "repository.findById" 실행 이후에도 (조회용)영속상태가 외부 메서드 종료시점까지 유지되는 것으로 이해했습니다. 하지만 이러한 조건이 내부 메서드에 적용된 requires_new로 분리가 되지 않는 점이 이해가 잘 가지 않습니다.. ㅠ
- 1
- 5
- 679
질문&답변
2021.10.02
@Transaction 전파 관련 문의
네 답변 감사합니다! 말씀하신대로 진행해서 정리해봤는데 다음과 같은 결과가 나왔습니다. AOP를 처음 사용해본거라, 조금 헷갈리는 부분이 있어서요~ㅠ 추가 질문 2가지가 있습니다. 1) 앞서 질문의 내부에서 호출된 메서드 "capsule"을 별도 클래스(TestComponent)로 분리하였습니다. @RequiredArgsConstructor@Componentpublic class TestComponent { private final MemberRepository memberRepository; private final EntityManager em; @Transactional(propagation = Propagation.REQUIRES_NEW) public void capsule(Long id) { Member member2 = em.find(Member.class, id); System.out.println("member2 = " + member2); }} 2.1) 호출하는 메서드에 @Transactional 적용 안함 Controller의 "findMember5" 메서드에서 member find를 진행하고, 1)의 "capsule"메서드를 호출하였습니다. 이 때 "findMember5" 메서드에 @Transactional은 적용하지 않았습니다. @GetMapping("/em/{id}")// @Transactional public void findMember5(@PathVariable("id") Long id) { Member member1 = memberRepository.findById(id).get(); System.out.println("member1 : " + member1); testComponent.capsule(id); } 이 경우, 동일한 member가 호출되었습니다. 간단히 그림으로 보면 다음과 같습니다. (사진) 2.2) 호출하는 메서드에 @Transactional 적용(주석 제거) (사진) @Transactional을 외부에도 적용했을 경우에는 member1, member2가 다른 결과가 나왔습니다. 이 경우에는 내부 메서드의 @Transactional(REQUIRES_NEW)가 정상적으로 동작한 것으로 이해했습니다. 질문 1 : 외부 메서드의 @Transactional 적용 여부에 따라 위와 같은 결과가 나오는데, 이유를 설명해주실 수 있으실까요? 오히려 2.1)의 트랜잭션이 완벽하게 분리가 될 것으로 생각했습니다. 질문 2 : 다른 AOP의 경우에도 @Transacional의 case(내부 @Transactional에만 Requires_new 적용)와 마찬가지로 내부 어노테이션에 다른 기능(옵션)을 부여할 수 있나요?
- 1
- 5
- 679
고민있어요
2021.06.03 11:31
이후 진행사항 문의
- 0
- 1
- 197
질문&답변
2021.06.03
@MainDiscountPolicy 삭제시 오류
안녕하세요 영한님! 비슷한 것으로 궁금해서 추가 질문드립니다. 그럼 해당 에러는 AllBeanTest의 컨테이너 생성 과정 중 -> AutoAppConfig.class를 통해 Component Scan을 통한 OrderServiceImpl의 생성과정에 생기는 NoUniqueBeanDefinitionException이라고 이해하면 될까요?
- 0
- 2
- 305