인프런 커뮤니티 질문&답변

dionisos198님의 프로필 이미지

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

영속성 전이(CASCADE)와 고아 객체

JPA flush 와 commit 의 차이가 뭔지 이해가 안갑니다.

작성

·

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

dionisos198님의 프로필 이미지
dionisos198
질문자

이해했습니다! 답변 안해주셔도 되어용!

0

안녕하세요, 인프런 AI 인턴입니다.

dionisos198님의 질문에 대해, JPA에서 flushcommit의 차이에 관한 궁금증에 도움이 될만한 내용을 찾았습니다.

질문에서 언급한 바와 같이, flush는 영속성 컨텍스트의 내용을 데이터베이스에 반영(동기화)하는 과정이며, 이는 데이터베이스와 영속성 컨텍스트 사이의 스냅샷을 일치시키는 작업입니다. 반면, commit은 진행 중인 트랜잭션을 완료하고 해당 트랜잭션내의 모든 변경 사항들을 데이터베이스에 영구적으로 반영하는 과정입니다.

다음은 데이터베이스와 영속성 컨텍스트간의 동기화와 트랜잭션 커밋에 대한 설명을 제공하는 내용이 포함된 페이지입니다:

  • 플러시와 커밋이 어떻게 구분되는 것인지 궁금합니다.
    이 페이지에는 플러시가 영속성 컨텍스트 내용을 데이터베이스에 동기화하는 것이고, 이는 에러 발생 시 롤백이 가능한 단계까지만 반영하는 작업임을 설명합니다. 반면, 트랜잭션 커밋은 작업 내용을 데이터베이스에 확정하는 작업으로, 해당 단계 이후에는 롤백이 불가능합니다.

  • flush commit 이해가 안되는부분이있습니다.
    이 게시글에서는 flush와 commit의 차이, 특히 플러시 발생 시점과 트랜잭션 커밋 과정에서의 데이터베이스상의 변화에 관한 설명이 이루어지고 있습니다. 이는 @Transactional 트랜잭션의 범위 내에서 실행된 영속성 컨텍스트의 변경 사항들이 어떻게 데이터베이스에 반영되는지를 설명하고 있습니다.

이 내용들을 근거로, dionisos198님의 코드에서 saveAndFlush를 호출할 때 발생하는 즉각적인 쿼리 발생 현상과, @Transactional의 범위가 끝나야 실제 데이터베이스에 데이터가 반영되는 현상에 대해 이해를 돕고자 합니다. flush는 데이터베이스와 영속성 컨텍스트 사이의 동기화를 담당하지만, 실제 데이터의 영구적인 저장(확정)은 트랜잭션이 커밋될 때 완료됩니다. 따라서, 트랜잭션이 끝나기 전까지는 변경 사항이 데이터베이스에 반영되지 않는 것이 일반적입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.