작성
·
337
1
안녕하세요. 제가 스프링부트로 프로젝트를 만들던 중 궁금한 점이 생겨서 질문드립니다.
현재 제 상황은 서비스 단에서 기본적인 설정을 @Transactional(noRollbackFor = WebClientResponseException.class)로 해놓고 DB접근 기술은 JPA를 사용했습니다. 그리고 통합테스트에서 테스트 코드를 통해 해당 예외가 발생했을 때, 롤백이 되는지 안되는지를 확인하는 과정이었습니다. 저는 당연히 예외 발생 전까지의 트랜잭션 내에서 CRUD가 롤백되지 않고 DB에 반영이 되었다고 생각했는데 테스트 결과, DB에 반영이 안되었습니다.
그 원인으로 제가 생각할 때, JPA의 특성인 쓰기 지연이 발생해 영속성 컨텍스트에만 우선 entity들을 등록해놓고 해당 트랜잭션이 정상적으로 종료될 때, 영속성 컨텍스트에 저장된 엔티티들을 DB에 저장하고 비정상적으로 종료될 때(예외발생), 영속성 컨텍스트에 저장된 엔티티들을 DB에 반영안하는 것 같습니다. 그래서 설정 값으로 noRollbackFor 을 설정하더라도 DB에 쿼리가 안날라간 상태(영속성 컨텍스트에만 반영된 상태)이면 해당 값은 롤백 대상이 아닌것으로 판단하는 것이라 생각합니다. 그래서 실제로 제가 em.persist(특정 엔티티)를 하고 바로 em.flush()를 하니까 테스트코드가 성공하는 것을 확인했습니다.
혹시 제가 생각하는 부분이 맞는지 여쭙고 싶어서 이렇게 질문을 드리게 되었습니다. 답변해주신다면 정말 감사하겠습니다!!
답변 1
0
안녕하세요. mission0705님
결론부터 말씀드리면, 테스트 자체가 잘못된 것 같아요.
왜냐하면 예외가 발생해서 noRollbackFor가 정상 동작했다면 트랜잭션 커밋이 발생할 것인데요.
그러면 이 시점에 em.flush()도 정상 호출되게 됩니다.
관련해서 더 자세한 내용은 스프링 DB 1편, 2편 강의를 참고해주세요.
감사합니다.
감사합니다!! 제가 다시 em.flush()를 제거하고 테스트 실행했는데 잘되네요 ㅎㅎㅎ 이전에 뭔가 테스트 코드상에서 실수가 있었던 것 같습니다.!!