[Spring] 영속성 컨텍스트

JJoSuk·2023년 7월 25일
0

영속성 컨텍스트

영속성 컨텍스트

  • 엔티티를 영구 저장하는 환경이라는 뜻
  • EntityManager.persist(entity)
  • persist 메서드 는 db 에 저장하는게 아니라 엔티티 영속성 컨텍스트에 저장한다고 보면 된다.
  • 눈에 보이지 않는다.
  • 엔티티 매니저를 통해서 영속성 컨텍스트에 접근한다.

엔티티에는 생명주기가 있다.

  • 비영속(new/transient)

    • 전혀 관계 없는 새로운 상태
  • 영속(managed)

    • 영속성 컨텍스트에 관리되는 상태
  • 준영속(detached)

    • 영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제(removed)

    • 삭제된 상태
try {
        Member member = new Member();
        member.setId(100L);
        member.setName("HelloJPA"); // 여기까지는 비영속 상태

        em.persist(member); // 여기서부터는 영속 상태, 그렇다고 db에 저장된 상태는 아니고 영속성 컨텍스트 안에서 관리만 되는 상태

        tx.commit(); // 여기서 커밋을 해야 영속성 컨텍스트 안에서 관리되고 있는 데이터를 db 에 들어간다.
    } catch (Exception e) {
        tx.rollback();
    } finally {
        em.close();
    }
    emf.close();
}

영속 엔티티의 동일성 보장

Member a = em.find(Member.class, “member1”);
Member b = em.find(Member.class, “member1”);

System.out.println(a == b); // 동일성 비교를 해보면 true

1차 캐시로 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공해준다.


엔티티 등록 관련

Member member1 = new Member(150L, "A");
Member member2 = new Member(160L, "B"); // 비영속

em.persist(member1);
em.persist(member2); // 영속 상태이며, sql 에 데이터를 보내지 않는다.
// ================
tx.commit(); // commit 을 해야 영속성 컨텍스트에 벗어나 DB 에 insert sql 을 보내 저장한다.

엔티티 수정 관련

Member member = em.find(Member.class, 150L);
            member.setName("ZZZZ");
            
//            em.persist(member);

commit 을 안해도 데이터베이스를 확인해보면 데이터가 변한걸 확인 할 수 있다.
여기서 초기화를 하면 값이 원래대로 돌아오고, commit 을 하게 된다면 변경된 값이 데이터베이스에 반영된다.

추가) remove 를 사용할 경우 삭제를 진행한다.


플러시

영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다.

플러시 발생 시

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

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

  • em.flush() 직접 호출
  • 트랜잭션 커밋 - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출
Member member = new Member(200L, "member200");
em.persist(member); // 영속 상태

em.flush(); // 플러시 사용 시 바로 데이터베이스에 반영

em.commit;

플러시 정리

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

준영속

준영속 상태

  • 영속 -> 준영속
  • 영속 상테의 엔티티가 영속성 컨텍스트에서 분리(detached)
  • 영속성 컨텍스트가 제공하는 기능을 사용 못함
(detach)
Member member = em.find(Member.class, 100L);
member.setName("AAAA"); // 영속 상태지만,

em.detach(member); // 내부에서 외부로 전환해서 준영속 상태가 된다.
(clear)
Member member = em.find(Member.class, 100L);
member.setName("AAAA"); // 영속 상태지만,

em.clear(); // 내부에 있는 영속 상태 값을 전부 초기화 한다.
(close)
Member member = em.find(Member.class, 100L);
member.setName("AAAA"); // 영속 상태지만,

em.close(); // 영속성 컨텍스트를 아예 닫아버려서 이것도 역시 준영속 상태가 된다.
profile
안녕하세요

1개의 댓글

comment-user-thumbnail
2023년 7월 25일

이런 유용한 정보를 나눠주셔서 감사합니다.

답글 달기