작성
·
1K
0
제목 그대로입니다.
블로그 찾아보니 flush 는 영속성 컨텍스트의 내용을 DB에 동기화 시키는 것, 이라고 하고 커밋은 트랜잭션을 종료하는데 쓴다고하더라구요!.
@Transactional
public void likePost(final Member currentMember,final Long postId){
try{
postLockRepository.getLock(postId.toString());
final Post post = findPost(postId);
//post 의 작성자와 좋아요를 누르려는 사람의 ID 값이 같을 떄 예외
if (post.getMember().getId() == currentMember.getId()) {
throw new NotFoundException(ErrorCode.MESSAGE_NOT_FOUND);
}
//이미 눌러져 있을 때 deleteLikePost 수행, 없다면 saveLikePost 수행
likePostRepository.findByMemberIdAndPostId(currentMember.getId(), post.getId())
.ifPresentOrElse(likePost -> {
deleteLikePost(likePost, post);}, () -> {
saveLikePost(currentMember, post);
System.out.println("pp");
});
}
finally{
postLockRepository.releaseLock(postId.toString());
}
}
private void saveLikePost(final Member member,final Post post){
LikePost lp= LikePost.builder()
.post(post)
.member(member)
.build();
likePostRepository.save(lp);
System.out.println("gg");
post.increaseLikeCount();
postRepository.saveAndFlush(post);
System.out.println("kk");
}
이 코드에서 saveLikepost 를 실행하면 post 에 대한 좋아요 가 하나 증가합니다.
그리고 saveAndFlush를 통하면 update 쿼리가 바로 나가더라구요!.
이 같이 쿼리를 발생시키고
flush 를 했으니 영속성 컨텍스트에 있는 post 의 like_count 는 1이 증가되어야 합니다.
또한 likePostRepository.save() 도 역시 insert 쿼리가 나가고요!
질문 요약:
저희가 알고있는 개념대로라면
영속성 컨텍스트에 있는 @Transactional 안에 있는 Save를 한 대상(LikePost) 와 @Transactional 안에 있는 SaveFlush 대상 역시 FLUSH를 통해 DB와 동기화 시킨다고 생각했습니다. (DB에 동기화시켰으니까 insert 하는 대상은 DB에 생겨야 하고, update 한 거는 update 가 제대로 반영이 되어야 한다고 생각했습니다)
그런데 위 과정에서 디버깅을 해보니(하이버네이트로 쿼리가 날라가는 것은 확인이 되었습니다) 실제 DB에 데이터가 들어가지 않고 @Transactional 이 끝나야 DB에 반영이 되더라고요!!
제가 동기화에 대해 이해를 잘 못하고 있는 걸까요?
답변 2
0
0
안녕하세요, 인프런 AI 인턴입니다.
dionisos198님의 질문에 대해, JPA에서 flush
와 commit
의 차이에 관한 궁금증에 도움이 될만한 내용을 찾았습니다.
질문에서 언급한 바와 같이, flush
는 영속성 컨텍스트의 내용을 데이터베이스에 반영(동기화)하는 과정이며, 이는 데이터베이스와 영속성 컨텍스트 사이의 스냅샷을 일치시키는 작업입니다. 반면, commit
은 진행 중인 트랜잭션을 완료하고 해당 트랜잭션내의 모든 변경 사항들을 데이터베이스에 영구적으로 반영하는 과정입니다.
다음은 데이터베이스와 영속성 컨텍스트간의 동기화와 트랜잭션 커밋에 대한 설명을 제공하는 내용이 포함된 페이지입니다:
플러시와 커밋이 어떻게 구분되는 것인지 궁금합니다.
이 페이지에는 플러시가 영속성 컨텍스트 내용을 데이터베이스에 동기화하는 것이고, 이는 에러 발생 시 롤백이 가능한 단계까지만 반영하는 작업임을 설명합니다. 반면, 트랜잭션 커밋은 작업 내용을 데이터베이스에 확정하는 작업으로, 해당 단계 이후에는 롤백이 불가능합니다.
flush commit 이해가 안되는부분이있습니다.
이 게시글에서는 flush와 commit의 차이, 특히 플러시 발생 시점과 트랜잭션 커밋 과정에서의 데이터베이스상의 변화에 관한 설명이 이루어지고 있습니다. 이는 @Transactional
트랜잭션의 범위 내에서 실행된 영속성 컨텍스트의 변경 사항들이 어떻게 데이터베이스에 반영되는지를 설명하고 있습니다.
이 내용들을 근거로, dionisos198님의 코드에서 saveAndFlush
를 호출할 때 발생하는 즉각적인 쿼리 발생 현상과, @Transactional
의 범위가 끝나야 실제 데이터베이스에 데이터가 반영되는 현상에 대해 이해를 돕고자 합니다. flush
는 데이터베이스와 영속성 컨텍스트 사이의 동기화를 담당하지만, 실제 데이터의 영구적인 저장(확정)은 트랜잭션이 커밋될 때 완료됩니다. 따라서, 트랜잭션이 끝나기 전까지는 변경 사항이 데이터베이스에 반영되지 않는 것이 일반적입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.