@Transactional 없이 save() vs saveAndFlush()
public Member saveMember(MemberDTO memberDTO){
Member member = Member.create(memberDTO);
member = memberRepository.save(member);
member.setName("TaeHyun");
return member; // break point 설정
}
아래와 같이 console에 출력되지만 변경된 name(태현) 은 입력되지 않는다.
Hibernate :
insert
into
member
(name, uuid ... )
values
(?,?, ... )
public Member saveMember(MemberDTO memberDTO){
Member member = Member.create(memberDTO);
member = memberRepository.saveAndFlush(member);
member.setName("TaeHyun");
return member; // break point 설정
}
아래와 같이 console에 출력되지만 변경된 name(태현) 은 입력되지 않는다.
Hibernate :
insert
into
member
(name, uuid ... )
values
(?,?, ... )
@Transactional 있는 상태에서 save() vs saveAndFlush()
@Transactional
public Member saveMember(MemberDTO memberDTO){
Member member = Member.create(memberDTO);
member = memberRepository.save(member);
member.setName("TaeHyun");
return member; // break point 설정
}
@Transactional
public Member saveMember(MemberDTO memberDTO){
Member member = Member.create(memberDTO);
member = memberRepository.saveAndFlush(member);
member.setName("TaeHyun");
return member; // break point 설정
}
둘다 breakpoint까지는 update 되지 않지만 함수가 종료된 후에 update가 된다. 결국 여기까지도 두개다 같은 동작을 한다. 그렇다면 도대체 뭐가 차이 일까?
@Transactional 있는 상태에서 save() vs saveAndFlush() 후 set을 여러번 하는 경우
각각 save 문 뒤에 breakpoint를 설정했는데 어떻게 될까? save 할때마다 update 문이 날아갈까?
@Transactional
public Member saveMember(MemberDTO memberDTO){
Member member = Member.create(memberDTO);
member = memberRepository.save(member);
member.setName("TaeHyun");
member = memberRepository.save(member);
member.setName("TaeHyun2");
member = memberRepository.save(member);
member.setName("TaeHyun3");
return member; // break point 설정
}
- 첫번째 breakpoint : insert query 출력 / db 업데이트 안됨
- 두번째 breakpoint : query 출력 없음 / db 업데이트 안됨
- 세번째 breakpoint : query 출력 없음 / db 업데이트 안됨
- 메소드 종료 후 : update query 출력 / db 업데이트 됨
즉, 실제 디비에 update는 TaeHyun3만 된 것이다.
@Transactional
public Member saveMember(MemberDTO memberDTO){
Member member = Member.create(memberDTO);
member = memberRepository.saveAndFlush(member);
member.setName("TaeHyun");
member = memberRepository.saveAndFlush(member);
member.setName("TaeHyun2");
member = memberRepository.saveAndFlush(member);
member.setName("TaeHyun3");
return member; // break point 설정
}
- 첫번째 breakpoint : insert query 출력 / db 업데이트 안됨
- 두번째 breakpoint : update query 출력 / db 업데이트 안됨
- 세번째 breakpoint : update query 출력 / db 업데이트 안됨
- 메소드 종료 후 : update query 출력 / db 업데이트 됨
Hibernate:
update
member
set
name=?,
...
where
id=?
결론
saveAndFlush()라고 해서 바로 db에 업데이트를 하는 flush가 아니라 쓰기 지연 SQL 저장소 내로 flush를 하는 과정인거 같다. 어째뜬, 효율성 측면에서는 saveAndFlush() 보다는 save()를 권장하는 것 같다.
'Back-End > JPA' 카테고리의 다른 글
16장. 트랜잭션과 락, 2차 캐시 및 내 생각 (0) | 2019.11.13 |
---|---|
14장. JPA 컬렉션과 부가기능 (0) | 2019.11.12 |
ObjectOptimisticLockingFailureException (0) | 2019.11.02 |
N+1 문제 해결하기 ( fetch join, @EntityGraph ) (0) | 2019.08.14 |
JPA 1차 캐시 - Database와 동기화가 되지 않은 데이터를 읽는 문제 (0) | 2019.04.23 |