20.01.16 01:04 작성
·
256
0
영한님 안녕하세요.
이제 곧 Spring Data JPA 과정을 들을 예정인데, 앞서서 한 가지 문의 드립니다.
Spring Data JPA 의 save 메소드에는 @Transaction 어노테이션이 선언되어 있더군요.
그래서 그런지 순수JPA 과정에서 배웠던 em.persist() 와 다르게
save 가 호출되는 그 순간에 insert 쿼리가 바로 로그에 찍히더군요..
그럼 commit 이 됐다는 증거 같은데
save 메소드가 호출된 Service Layer 단에서 @Transcation 어노테이션 선언을 한 경ㅇ
save 메소드 호출 이후, 강제로 Exception 을 발생시키면
insert 쿼리는 로그에 찍히지만, 최종 결과로는 rollback 이 이뤄지는 것 같습니다.
이런 경우, 부모 트랜잭션을 물려 받는 상황으로 이해가 되는데
어떻게 commit 된 쿼리가 rollback 이 이뤄질 수 있는 지 원리를 좀 알고 싶어요.
답변 1
0
2020. 01. 16. 18:31
안녕하세요. 아리마님
서비스Tx, 리포지토리Tx 이렇게 트랜잭션을 구분하면
서비스Tx가 시작되고 그 다음에 리포지토리Tx를 실행할 꺼에요. 그러면 리포지토리Tx는 서비스Tx를 그대로 이어 받습니다.
그리고! 여기가 가장 중요한데, 리포지토리Tx가 종료될 때 Commit을 하지 않습니다!
insert 쿼리가 날라가는 것과 commit을 하는 것은 분리되어 있는 과정입니다^^!
이후 서비스Tx가 종료될 때 commit이 호출됩니다.
그러면 아리마님이 보셨다는 save가 호출되는 순간에 insert가 호출되었다는 것은 뭘까요?
정확히 이야기하면 JPA가 영속성 컨텍스트를 플러시 해서 그런건데요.
플러시는 다음 경우에 발생합니다.
1. 트랜잭션 커밋
2. JPQL 실행 직전
3. (이건 약간 예외) PK 매핑 전략이 IDENTITY일때(이 전략은 데이터베이스에 입력을 해야 PK를 얻을 수 있으므로)
이 3가지 경우에 해당하는지 한번 보시면 좋을듯요^^