엔티티 매니저 팩토리와 엔티티 매니저
데이터베이스를 하나만 사용하는 애플리케이션은 일반적으로 하나의 엔티티 매니저 팩토리를 사용한다
엔티티 매니저가 필요할 때마다 엔티티 매니저 팩토리에서 엔티티 매니저를 생성하면 된다
- 엔티티 매니저는 여러 스레드가 동시에 접근하는 경우 동시성 문제가 발생해 스레드간 공유를 하면 안된다
영속성 컨텍스트란?
영속성 컨텍스트는 엔티티를 영구 저장하는 환경이다
persist() 메서드를 통해 엔티티 매니저는 엔티티를 영속성 컨텍스트에 저장한다
엔티티의 생명주기
- 비영속(new/transient): 영속성 컨텍스트와 전혀 관계가 없는 상태
- 영속(managed): 영속성 컨텍스트에 저장된 상태 (엔티티가 관리되는 상태)
- 준영속(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태
- 삭제(removed): 영속성 컨텍스트와 데이터베이스에서 삭제된 상태
영속성 컨텍스트의 특징
영속성 컨텍스트는 엔티티를 식별자 값으로 구분하므로 영속 상태는 식별자 값이 반드시 존재해야 한다
엔티티 조회
영속성 컨텍스트 내부에 가지고 있는 캐시를 1차 캐시라고 한다
영속 상태의 엔티티는 모두 이곳에 저장된다
엔티티를 조회할 때 먼저 1차 캐시에서 엔티티를 조회하고 없는 경우 데이터베이스에서 조회한다
같은 엔티티를 반복해서 조회하더라도 영속성 컨텍스트는 1차 캐시의 같은 인스턴스를 반환한다
-> 영속성 컨텍스는 성능상의 이점과 엔티티의 동일성을 보장한다
엔티티 등록
엔티티 매니저는 트랜잭션을 커밋하기 전까지 INSERT SQL을 모아두고 커밋할 때 모아둔 쿼리를 데이터베이스에 보내는데 이를 쓰기 지연(transactional write-behind)이라 한다
-> 성능을 최적화할 수 있다
트랜잭션내에서는 여러 개의 INSERT SQL이 실행되는 경우 쿼리를 하나씩 실행하나 모아서 한번에 실행하나 결과의 차이가 없다
- 정상적으로 커밋되면 모두 데이터베이스에 저장되고 롤백되면 모두 저장되지 않는다
엔티티 수정
JPA로 엔티티를 수정하는 경우 단순히 엔티티를 조회해서 데이터만 변경하면 된다
엔티티의 변경 사항을 자동으로 데이터베이스에 반영하는 기능을 변경 감지(dirty checking)라고 한다
- 변경 감지는 영속성 컨텍스트가 관리하는 엔티티에 대해서만 적용된다
- 변경 감지로 인해 실행되는 쿼리는 기본적으로 엔티티의 모든 필드에 대해 업데이트 하는 쿼리이다 (재사용 가능)
트랜잭션 커밋 과정
- 트랜잭션을 커밋하면 엔티티 매니저 내부에서 플러시가 호출된다
- 엔티티와 스냅샷을 비교해 변경된 엔티티를 찾는다
- JPA는 엔티티를 영속성 컨텍스트에 보관할 때 최초 상태를 복사해서 저장해두는데 이를 스냅샷이라고 한다
- 변경된 엔티티가 있으면 수정 쿼리를 생성해 쓰기 지연 SQL 저장소에 보낸다
- 쓰기 지연 저장소의 SQL을 데이터베이스에 보낸다
- 데이터베이스 트랜잭션을 커밋한다
엔티티 삭제
remove() 메서드를 사용해 엔티티를 삭제한다
엔티티를 즉시 삭제하는 것이 아니라 엔티티 등록과 비슷하게 삭제 쿼리를 쓰기 지연 SQL 저장소에 등록하고 트랜잭션을 커밋하면 실제 데이터베이스에 삭제 쿼리를 전달한다
데이터베이스에는 즉각적으로 반영되지 않지만 remove()를 호출하는 순간 영속성 컨텍스트에서는 제거된다
영속성 컨텍스트의 장점
- 1차 캐시
- 동일성 보장
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
- 지연 로딩
'스터디 > JPA' 카테고리의 다른 글
엔티티 매핑 - (2) (0) | 2025.02.08 |
---|---|
엔티티 매핑 - (1) (0) | 2025.02.08 |
영속성 관리 - (2) (0) | 2025.02.07 |
JPA란 무엇인가? (1) | 2025.02.06 |
JPA의 등장 배경 (0) | 2025.02.06 |