인프런 커뮤니티 질문&답변

이석주님의 프로필 이미지

작성한 질문수

스프링 DB 2편 - 데이터 접근 활용 기술

JPA는 트랜잭션이 커밋이 될때 insert 쿼리를 날린다

해결된 질문

24.01.18 18:25 작성

·

1.1K

0

예외와 트랜잭션 커밋, 롤백 - 활용 강의, 22:05 부분에서 이렇게 말씀해주셨는데요.

강의에서는 runtimeException() 테스트를 실행해 런타임 예외 발생시 저장한 order 객체가 롤백이 되는것을 보여주셨습니다.

직접 실행까지 했는데, 제가 궁금한것은 서비스 부분에 id 값을 찍어보았을때입니다.

 

서비스 코드

    @Transactional
    public void order(Order order) throws NotEnoughMoneyException {
        log.info("order 호출");
        System.out.println("order.getId() = " + order.getId());
        orderRepository.save(order);
        System.out.println("order.getId() = " + order.getId());

 

실행 결과

order.getId() = null
2024-01-18T18:04:45.879+09:00 DEBUG 14780 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(1612240940<open>)] for JPA transaction
2024-01-18T18:04:45.879+09:00 DEBUG 14780 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction
2024-01-18T18:04:45.879+09:00 TRACE 14780 --- [    Test worker] o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-01-18T18:04:45.886+09:00 DEBUG 14780 --- [    Test worker] org.hibernate.SQL                        : select next value for orders_seq
2024-01-18T18:04:45.899+09:00 TRACE 14780 --- [    Test worker] o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
order.getId() = 1

실제 insert 쿼리를 실행해야 DB에서 생성되는 id 값이 들어있더군요.

롤백이 되면 insert 쿼리를 DB에 안날린다고 하셨는데, insert 쿼리를 날려야 생기는 저 id 값은 정체가 무엇인가요?

 

답변 2

0

김영한님의 프로필 이미지
김영한
지식공유자

2024. 01. 19. 21:34

안녕하세요. 이석주님

이 부분을 이해하려면 JPA의 엔티티가 영속화 되는 과정을 이해해야 하는데요.

자세한 내용은 JPA 기본편에서 설명드립니다 🙂

감사합니다.

0

인프런 AI 인턴님의 프로필 이미지

2024. 01. 18. 18:32

안녕하세요, 인프런 AI 인턴입니다. 이석주님의 질문은 JPA의 트랜잭션 처리, 즉 실행 시점에서 ID 값이 어떻게 생성되는지와 관련된 것으로 이해됩니다. JPA에서 엔티티의 ID 생성 전략이 GenerationType.IDENTITY로 설정되어 있다면, 엔티티가 영속화(persist) 단계에 들어갈 때 바로 INSERT SQL을 데이터베이스에 전송하여 ID를 가져옵니다. 이 경우, @Transactional 내에서 실행되기 때문에 해당 트랜잭션이 커밋되거나, 롤백되기 전에 ID 값이 생성되어 배정됩니다.

이에 대해 다음과 같은 내용을 포함한 강의에서 해명된 부분이 있습니다:

  • 롤백 과정이 궁금합니다.

    김영한 강사님은 이 글에서 entityManager.persist()를 호출했을 때와 save()가 호출될 때 되는 쿼리 실행 시점과 롤백에 대해 설명하고 계십니다. 해당 부분에서 각 경우에 대한 트랜잭션이 어떻게 처리되는지 자세한 설명을 찾을 수 있습니다.

  • Test코드에 @Transaction 동작 문의

    이 질문에서도 @Transactional 어노테이션과 테스트 케이스에서의 롤백 동작에 대해 김영한 강사님이 설명을 제공하고 있습니다. 특히 테스트 케이스에서의 트랜잭션 처리와 롤백 동작에 대한 이해가 필요할 수 있습니다.

  • MemberServiceTest - 테스트에서 @Transaction의 롤백기능이 수행되지 않습니다

    이 질문에서는 김영한 강사님이 테스트 상황에서 @Transactional 어노테이션이 붙은 메서드 내의 트랜잭션 처리와 JPQL을 실행할 때 일어나는 플러시(Flush) 현상에 대해 설명하고 계십니다.

이러한 기존 질문과 답변들을 참고하시면, JPA에서의 트랜잭션 처리와 ID 값 생성, 롤백과 커밋의 관계등에 대해 좀 더 명확히 이해하실 수 있을 것 같습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.