Spring/JPA

플러시 & 준영속 상태 정리

느리지만 꾸준하게 2022. 4. 12. 14:07

플러시

  • 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것

INSERT SQL / DELETE SQL / UPDATE SQL이 데이터베이스에 날라가는거라고 보면된다.

 

 

 

 

플러시 발생

  • 변경 감지(Dirty checking)
  • 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
  • (등록, 수정, 삭제 쿼리)

 

영속성 컨텍스트를 플러시 하는 방법

  • em.flush() - 직접 호출
  • 트랜잭션 커밋 - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출

아래를 실행할 때 commit을 하게되면 insert문이 담기고

flush를 할 때 쿼리가 바로 DB에 반영이 된다.

try {
            // 영속
            Member member = new Member(200L, "member200");
            em.persist(member);
            
            em.flush();
            
            System.out.println("===================================");
            tx.commit();

 

 

그리고 예를 들어 아래 persist를 하게되더라도 

실제 쿼리가 데이터베이스에 날라가지 않는다.

즉 JPQL은 무조건 flush를 날려버린다. 그리고 A B C가 조회됨.

결론적으로 플러시는?

  • 영속성 컨텍스트를 비우지 않고
  • 영속성 컨텍스트의 변경된 내용을 데이터베이스에 동기화하고
  • 트랜잭션이라는 작업 단위가 중요한데 커밋 직전에만 동기화를 하면 된다.

 

준영속 상태

  • 영속 -> 준영속
  • 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)
  • 영속성 컨텍스트가 제공하는 기능을 사용 못함

준영속 상태로 만드는 방법

  • em.detach(entity)
  • 특정 엔티티만 준영속 상태로 전환

detach를 하게되면 JPA가 관련없어지고(영속성 컨텍스트에서 더 이상 관리를 안함) 커밋할 때 아무일도 일어나지 않는다.

즉 SELECT 쿼리만 나가고 업데이트 쿼리는 안나간다.

        try {
            // 영속
            Member member = em.find(Member.class, 150L);
            member.setName("ZZZZZ");

            em.detach(member);

            System.out.println("===================================");
            tx.commit();

 

  • em.clear()
  • 영속성 컨텍스트를 완전히 초기화
  • 엔티티 매니저 안에 있는 영속성 컨텍스트를 통채로 다 지워버린다.
try {
            // 영속
            Member member = em.find(Member.class, 150L);
            member.setName("ZZZZZ");

            em.clear();
            
            System.out.println("===================================");
            tx.commit();

 

그리고 같은 것을 다시 조회하면 영속성 컨텍스트가 없는것을 알고 다시 올려야지라고 판단한다. (em.clear()로 인해서 초기화가 되어서)

즉 쿼리가 두 번 나간다.

try {
            // 영속
            Member member = em.find(Member.class, 150L);
            member.setName("ZZZZZ");

            em.clear();

            Member member2 = em.find(Member.class, 150L);

            System.out.println("===================================");
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
//            e.printStackTrace();
        } finally {
            em.close();
        }
  • em.close()
  • 영속성 컨텍스트를 종료 

 

 

 

 

정리하자면

 

영속성 컨텍스트에 대해서 알아봄

  • ORM 객체와 관계형 데이터베이스 매핑하기와 영속성 컨텍스트에 대해서

 

비영속상태와 영속상태(persist해서 집어넣음)에 대해서

준영속 상태와 삭제한 상태(db에 delete 쿼리로 날리고 싶을 때)에 대해서

 

영속성 컨텍스트의 이점에 대해서 

  • 5가지

 

플러시 & JPQL 쿼리 실행시 & 준영속 상태에 관해서 알아보았다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<출처 김영한: 자바 ORM 표준 JPA 프로그래밍 - 기본편 >

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com