Backend/JPA

[JPA/Java Persistence API] 영속성 컨텍스트

냠냠:) 2021. 5. 10. 23:02

[우아한형제들 김영환님의 인프런 강의 자바 ORM 표준 JPA 프로그래밍 - 기본편을 수강하고 정리한 내용입니다]

 

 

엔티티 컨텍스트

"엔티티를 영구 저장하는 환경"이란 뜻을 가진 논리적인 공간.

애플리케이션과 데이터베이스 사이에서 객체를 관리, 조작한다. 엔티티 매니저를 통해 영속성 컨텍스트에 접근할 수 있다.

EntityManager.persist(entity)

엔티티 매니저를 생성하면 한 개의 영속성 컨텍스트가 생긴다.


엔티티의 생명주기

비영속 (new/transient)

  • 영속성 컨텍스트와 상관없이 생성된 객체 자체

영속 (Managed)

  • 영속성 컨텍스트에 관리되는 상태

준영속 (detached)

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

삭제 (removed)

  • 영속성 컨텍스트에서 삭제되어 DB에도 삭제된 상태

 

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


비영속

Member member = new Member();
member.setId("cgw981");
member.setName("춘식이");

 

영속

EntityManager em = emf.createEntityManager();   //emf = 엔티티 매니터 팩토리
em.persist(member);		//객체를 영속성 컨텍스트 내에 저장

 

준영속

em.detach(member);		//member 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태

 

삭제

em.remove(member);		//객체를 삭제한 상태(삭제)

영속성 컨텍스트 이점

  • 1차 캐시
  • 동일성(identity) 보장
  • 트랜잭션을 지원하는 쓰기 지연
  • 변경 감지(Dirty Checking)
  • 지연 로딩(Lazy Loading)
1차 캐시란?

영속성 컨텍스트 내부에 있는 공간

애플리케이션에서 저장한 객체를 1차 캐시에 저장. 이후 해당 객체를 DB에서 조회할 때 1차 캐시에 있는지 먼저 확인 후, 존재한다면 1차 캐시에 있는 객체 반환

*DB에서 단순 조회만 해도 1차 캐시에 저장*

동일성 보장?

1차 캐시로 REPEATABLE READ의 트랜잭션 격리 수준을 DB가 아닌 애플리케이션에서 제공


*REPEATABLE READ? -> 하나의 트랜잭션안에서 수행되는 특정 값에 대한 조회는 트랜잭션 내에서 항상 같은 값을 조회해야 한다. 
트랜잭션을 지원하는 쓰기 지연?

위의 코드를 보면, em.persist(member)가 =====의 사이가 아닌 커밋을 만난 순간 실행되는 것을 볼 수 있다.

em.persist시 쓰기 지연 SQL 저장소에 member에 대한 Insert문이 쌓이다가 commit을 만난 순간 flush된다.

변경 감지?

위에서 DB에서 조회만 해도 1차 캐시에 쌓인다고 했다. 

위에서 member1의 이름을 바꿔주면 commit or flush를 하게 되면 1차 캐시 내에 있는 스냅샷과 저장돼있는 Entitiy를 비교하여 변경된 값에 대한 Update문을 스스로 만들어서 DB에 날리게 된다.

 


플러시 (FLUSH)

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

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

플러시 하는 방법

em.flush();

em.commit();

플러시 모드 옵션

em.setFlushMode(FlushModeType.COMMIT);  //커밋할 때만 플러시

em.setFlushMode(FlushModeType.AUTO);	//커밋이나 쿼리를 실행할 때 플러시(Default)

 

*플러시 주의사항*

- 플러시 자체로 트랜잭션이 끝나는 것이 아닌 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화하는 작업.

- 준영속 상태의 엔티티는 플러시의 대상이 아님.

 

준영속 상태로 만드는 방법

em.detach(entitiy);		//엔티티 준영속 상태로 만들기

em.clear();			//엔티티 매니저 비우기 == 영속성 컨텍스트 비우가

em.close();			//엔티티 매니저 끝내기

 

반응형