작성
·
13
·
수정됨
0
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예
[질문 내용]
// @Transactional
public void update(Long id, String name, String city, String street, String zipcode) {
Address address = new Address(city, street, zipcode);
Member member = memberRepository.findOne(id);
member.setName(name);
member.setAddress(address);
}
위와 같이 update 메서드의 @Transactional
을 주석 처리하고 해봤습니다.
제 예상이라면 응답값이 새로워진 값이 아니라 기존의 값이 응답값으로 내려와야 할 것 같았습니다.
@PutMapping("/v2/members/{id}")
public UpdateMemberResponse updateMemberV2(
@PathVariable Long id,
@RequestBody @Validated UpdateMemberRequest request
) {
memberService.update(
id,
request.name,
request.city,
request.street,
request.zipcode
);
Member findMember = memberService.findOne(id);
return new UpdateMemberResponse(findMember.getId(), findMember.getName());
}
왜냐하면 결론적으로 엔티티 자체는 수정되었지만 DB에 쿼리가 날라가지 않았고
위 컨트롤러 코드에서 find 메서드는 엄연히 다른 트랜잭션에서 진행되니(애초에 업데이트는 트랜잭션이 없었지만) 다른 영속성 컨텍스트가 존재할 것이며,
1차 캐시또한 비워져있을 테니(애초에 업데이트는 영속성 객체를 가지고 있지 않았기에 1차캐시에 없음)
즉, 컨트롤러에서 find한 Member 객체는 새로 DB에서 가져온 객체 == 기존 객체 일테니
응답 값이 기존 값과 같아야할텐데 아래와 같이 달라진 값을 응답으로 내려주고 있었습니다.
왜 그런걸까요?
가입 응답
{
"name": "hello",
"city": "city",
"street": "street",
"zipcode": "12345"
}
수정 응답
{
"name": "hello@",
"city": "city@",
"street": "street@",
"zipcode": "12345@"
}
답변 2
0
안녕하세요. JHL님, 공식 서포터즈 y2gcoder입니다.
도움을 드리고 싶지만 질문 내용만으로는 답변을 드리기 어렵습니다.
OSIV 가 원인일 수도 있습니다! 자세한 건 실행 로그와 함께 봐야 할 것 같습니다 🙂
실제 동작하는 전체 프로젝트를ZIP파일로 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.
구글 드라이브 업로드 방법은 다음을 참고해주세요.
주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요
추가로 다음 내용도 코멘트 부탁드립니다.
1. 문제 영역을 실행할 수 있는 방법
2. 문제가 어떻게 나타나는지에 대한 상세한 설명 (오류 화면, 오류 로그 포함)
링크: 공식 서포터즈
링크: 자주하는 질문
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다. JHL님.
질문해주신 부분은 JPA의 영속성 컨텍스트와 트랜잭션의 관계에 대한 이해가 필요합니다.
JPA에서 “영속성 컨텍스트”는 특정 시점의 데이터베이스 상태를 메모리에 임시로 저장하는 역할을 합니다. 트랜잭션이 시작되면, JPA는 데이터베이스 상태를 영속성 컨텍스트에 로드하고, 모든 변경사항은 트랜잭션이 끝난 후에 데이터베이스로 커밋됩니다.
하지만, @Transactional
어노테이션이 없는 경우에는 변경 사항이 즉시 커밋되지 않습니다. 따라서 memberService.update()
메서드가 호출되었을 때, 실제로 데이터베이스에 반영은 되지 않았어야 합니다.
이 경우 수정 응답
에서 변경된 값이 내려오는 이유는 다음과 같습니다:
- 현재 코드상에서는 SQL 업데이트 쿼리가 수행되지 않아야 합니다. 그러나 테스트 환경에 따라 변경된 값이 캐시에 남겨져있는 경우가 있을 수 있습니다.
- 만약에 동작 결과가 예상과 다르다면, 이는 캐시나 테스트의 환경 설정과 연관이 있을 수 있습니다. 특히 테스트 컨텍스트를 사용할 때는 주의가 필요합니다.
이 문제를 보다 정확히 해결하기 위해 실행 환경을 살펴볼 필요가 있습니다. 테스트 과정을 확인하시고 데이터베이스 로그를 분석해 보신다면 보다 정확한 원인을 파악할 수 있습니다.
이와 관련하여, 김영한 지식공유자님의 강의에서 OSIV(Open Session In View)와 같은 개념도 공부하시면 도움이 되실 것입니다. 다음의 링크를 참고해 주시면 감사하겠습니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.