Daily log

/* 과거 다른 블로그에 작성했던 내용입니다. */

 

 

JPA를 공부하면 항상 따라오는 용어가 있다.

영속성 컨텍스트.

Entity를 영구 저장하는 환경이라는 뜻이라고 한다.

 

EntityManger.persist(entity);

위와 같이 영속성 컨텍스트에 entity를 insert 한다. 

Entity의 생명주기

- 비영속(new/transient): 영속성과 전혀 관계가 없는 새로운 상태

- 영속(managed): 영속성 컨텍스트에 관리되는 상태

- 준영속(detached): 역속성 컨텍스트에 저장되었다가 분리된 상태

- 삭제(removed): 삭제된 상태

 

1. 비영속

 - 객체를 생성했지만 persist를 하지 않아 영속성 컨텍스트에는 관리되지 않는다.

 - 예:

Member member = new Member("MAN");

2. 영속

 - 생성된 객체를 persist하여 영속성 컨텍스트에서 관리되도록 한 상태.

 - DB에 저장된 상태는 아니다. => 1차 캐시

 - 예: 

  EntityManager em = emf.createEntityManager(); // emf: EntityManagerFactory
  em.getTransaction().begin();
  em.persist(member); // 영속성 컨텍스트에서 관리

 

1차 캐시에 대해

 - EntityManager로 한 트랜잭션에서 데이터를 조회시 영속성 컨텍스트, 즉 1차 캐시에 데이터가 존재하면 커리를 하지 않고 가져온다. 만약 1차 캐시에는 데이터가 없고 DB에 데이터가 있다면 DB를 조회 후 1차캐시에 데이터를 보관한다. 하지만 트랜잭션이 끝나면 1차 캐시는 삭제되기 때문에 큰 의미가 없을 수 있다.

 

쓰기 지연 SQL 저장소

 - 데이터를 persist 하면 1차 캐시에 데이터가 입력되고 동시에 쓰기 지연 SQL 저장소라는 공간에도 입력한 데이터가 쌓인다. 만약 commit 하지 않고,  2차 persist를 하면 앞에서 동작한 방식대로 1차 캐시와 쓰기 지연 SQL 저장소에 데이터가 계속 쌓인다. 그러다 commit를 하면 쓰기 지연 SQL 저장소에 쌓여 던 데이터가 DB로 flush된 후 commit 되어 저장된다.

 

변경 감지(Dirty Checking) ( UPDATE 할 때...)

 - em.find로 데이터를 조회하면 영속성 컨텍스트에는 조회한 데이터가 등록이 되는데, 이때 조회한 Entity와 같은 데이터의 스냅샷이 발생한다. 그리고 조회한 데이터의 값을  setter로 변경하면 영속성 컨텍스트에 등록되어 있는 Entity의 값이 변경된다. 이후 commit을 하면 영속성 컨텍스트에 있는 Entity와 최초 불러왔던 스냅샷 데이터와 비교하여 변경이 감지되면 update 쿼리가 발생하게 된다. 

 - 위와 같은 이유로 update를 할 때는 insert와 다르게 persist로 영속성 컨텍스트에 반영하지 않아도 된다.

   (setter할 때 이미 영속성 컨텍스트의 값은 변경됨)

 

플러시(Flush)

 - 쓰기 지연 SQL 저장소에 쌓인 쿼리를 DB에 반영(동기화)

 - flush를 해보 1차 캐시가 삭제되지 않는다. ( 영속성 컨텍스트를 비우지 않음)

 - flish 하는 방법: em.flush(), 트랜잭션 commit, JPQL 쿼리 실행

 

JPQL 쿼리 실행시 플러시(Flush)에 대해

 - persist로 저장소에 쌓인 입력 SQL이 여러개 있다고 가정했을 때, 따로 flush나 commit을 하지 않은 상태에서 JPQL로 select를 하면 문제가 발생할 요지가 있기 때문에 JPQL로 select하기 전에 flush를 실행하여 저장소에 쌓인 입력 쿼리를 실행하고 입력된 데이터를 select 한다.

 - 하지만 옵션으로 commit시에만 flush 하도록 설정하 수 있다. 

   em.setFlushMode(FlushModeType.COMMIT) // COMMIT 시에만 flush 되도록 변경, 기본값: AUTO

 

3. 준영속

준영속성 상태로 만드는 방법

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

 - em.clear() : 영속성 컨텍스트를 완전히 초기화

 - em.close() : 영속성 컨텍스트를 종료

공유하기

facebook twitter kakaoTalk kakaostory naver band