MemberServiceTest
실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 섹션 4 회원 기능 테스트 강의 질문입니다.
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
class MemberServiceTest {
@Autowired MemberService memberService;
@Autowired MemberRepository memberRepository;
@Test
public void 회원가입() throws Exception {
// given
Member member = new Member();
member.setName("kim");
// when
Long saveId = memberService.join(member);
// then
assertEquals(member, memberRepository.findOne(saveId));
}
@Test
public void 중복_회원_예외() throws Exception {
// given
Member member1 = new Member();
member1.setName("kim");
Member member2 = new Member();
member2.setName("kim");
// when & then
assertThrows(IllegalStateException.class, () -> {
memberService.join(member1);
memberService.join(member2);
});
}
}Junit5를 사용했다는 점을 제외하고는 강의와 똑같이 코드를 작성했습니다.
이때 회원가입관련 테스트에서 강의에서는 insert문이 나가지 않지만 저는 따로 Rollback을 false로 설정하지 않아도 insert문이 실행되더군요. 이유가 궁금합니다.

사진에서 확인할 수 있듯이 Rollback이 되었기 때문에 트랜잭션이 커밋되지 않아 insert 쿼리가 발생하면 안될 것 같은데 왜 실행되는지 이유를 모르겠습니다.
답변 2
0
안녕하세요. constela10님, 공식 서포터즈 코즈위버입니다.
쿼리 내용으로 보아 중복회원가입 시 insert 쿼리가 발생하는 것으로 보입니다.
중복회원 검증시 findByName("사용자이름") 과 같이 키가 아닌 값으로 데이터를 조회하는 부분이 있을 수 있습니다. 이 경우 JPA는 조회쿼리를 수행하기전에 데이터베이스와 동기화(persist) 작업을 수행하며 이 때 inser 쿼리가 발생합니다.
JPA에서 JPQL을 수행하기전에 강제로 데이터베이스 동기화가 발생하는 것과 마찬가지라고 생각해주세요.
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
constela10님께서 질문하신 내용은 JUnit5를 사용하여 SpringBootTest와 @Transactional 어노테이션을 활용한 테스트 중, @Transactional로 인해 롤백이 예상되지만 실제로 INSERT 문이 실행되는 이유와 관련이 있습니다.
Spring Boot와 JPA를 사용한 개발에서 JUnit 테스트를 실행할 때 @Transactional 어노테이션은 테스트가 끝난 후 데이터를 초기 상태로 롤백하여 DB에 영구적인 변경을 남기지 않도록 돕습니다. 그러나 실제로 SQL 로그를 통해 INSERT 문이 실행되는 것을 확인할 수 있습니다. 이는 스프링 테스트 컨텍스트가 @Transactional 어노테이션이 붙어 있을 경우 테스트 실행 도중에는 실제 DB에 데이터를 추가하지만, 테스트 완료 시에 이를 롤백하기 때문입니다. 즉, 테스트 실행 중 데이터 접근 로직을 검증하기 위해 실제 SQL이 실행되지만, 테스트가 종료될 때 모든 데이터 변경 사항은 롤백되어 반영되지 않는 것입니다.
constela10님의 경우도 이러한 상황에 해당됩니다. 로그에서 INSERT 문이 실행된 것으로 보이지만, 마지막에 Rollback이 되어 실제 데이터베이스에는 이 변경 사항들이 반영되지 않은 상태입니다.
섹션 4 - 회원 기능 테스트 강의에서 중복_회원_예외()메서드를 실행할 때 INSERT 쿼리가 실행되는 이유 질문에서도 비슷한 상황에 대한 논의가 있었습니다. 이는 Spring Framework에서 제공하는 @Transactional 어노테이션의 동작 방식을 이해하는 데 도움이 될 수 있습니다.
이 과정에서 실험적으로 데이터를 다루고 싶을 때, 데이터의 영구적 변경을 원하지 않는 경우 @Transactional 어노테이션을 활용하는 것이 좋습니다. 실험적인 변경을 DB에 반영해 본 후 자동으로 롤백하는 기능으로, 테스트 케이스 작성 시 매우 유용하게 사용됩니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
OrderServiceTest 상문주문 테스트 시 update 쿼리 문의
0
27
1
sdk 설정 오류
0
68
2
오탈자 - @Transactional
0
63
1
src/test/resources 테스트 경로 문제
0
60
1
상품 등록후 H2 db 출력 순서 바꿀 수 있나요?
0
70
1
MemberRepositoryTest 실행오류
0
90
1
boot 4.x >>> trasasction rolled back log & p6spy(영한님, 수업 자료 업데이트 해주시면 감사하겠습니다!!)
1
197
2
강의 마지막 QueryDSL 사용 부분 질문있습니다
1
154
2
클라이언트에서 isbn과 author 수정 요청을 한 경우에 대해 질문드립니다.
0
57
1
도메인 모델 패턴 vs 트랜잭션 스크립트 패턴
0
80
1
기본 생성자
0
67
1
h2 DB 연결시 jdbc url 변경 이유가 궁금합니다.
0
107
1
멤버서비스테스트 부분에서 막힙니다.
0
174
4
실무에서도 EntityManager를 이용해서 많이 작업하는 편일까요?
0
124
1
초반에 h2 다운로드 과정 꼭 필요한가요?
0
129
2
자신 필드에도 get으로 접근하는 이유가 있을까요?
0
122
1
24분 27초 연관관계 편의 메서드 위치
0
118
1
단건 주문만 가능하게 한건 의도한 부분이신가요?
0
114
2
빌드 툴, Gradle
0
65
1
h2연결은 된 것 같은데 엔티티 테이블까지 작성 후 확인해보아도 테이블이 안보입니다
0
82
2
Repository에서 EntityManager 주입 방식 차이
0
97
1
롬복과 사용자 정의 setter 메서드
0
78
1
주문 목록 조회 fetch join 질문드립니다
0
91
1
dirty checking 질문드립니다.
0
87
1





