728x90
반응형
첫번째 그림에 대한 설명
- 웹 애플리케이션에서 EntityManager를 효율적으로 관리하고, 데이터베이스와의 연결을 관리하기 위해 EntityManagerFactory를 하나 생성한다.
- 그리고 EntityManagerFactory에서 각 요청에 대해서 하나씩 EntityManager를 생성한다.
- 그림에서 보면 EntityManager1은 데이터베이스 커넥션을 사용하지 않기 떄문에 커넥션을 얻지 않은 상태이다.
- 그와 반면 EntityManager2는 커넥션을 사용중이고, 보통은 트랜잭션을 시작할 때 커넥션을 획득한다.
EntityManager란?
- JPA(Java Persistence API)의 핵심 인터페이스 중 하나로, 애플리케이션에서 데이터베이스와의 상호작용을 관리하는 역할.
- 이를 통해 엔티티(Entity)를 데이터베이스에 저장하거나, 수정, 삭제, 조회하는 등의 작업을 수행할 수 있다.
EntityManagerFactory란?
- JPA(Java Persistence API)에서 EntityManager 객체를 생성하는 팩토리 객체.
- 데이터베이스와 상호작용하는 애플리케이션에서 EntityManager는 개별 트랜잭션이나 작업을 관리하는 반면, EntityManagerFactory는 애플리케이션 전체에서 사용되는 단일 인스턴스로, EntityManager 객체들을 생성하고 관리하는 역할.
두번째 그림에 대한 설명
- 엔티티의 생명주기는 4가지로 나눌 수 있다.
- 비영속(new / transient)
- 영속성 컨텍스트와 전혀 관계가 없는 상태
- 엔티티 객체를 생성하고 아직 저장을 하지 않아서, 영속성 컨텍스트나 데이터베이스와는 전혀 관련이 없는 상태
- 영속(managed)
- 영속성 컨텍스트에 저장된 상태
- 엔티티 매니저를 통해 엔티티를 영속성 컨텍스트에 저장(persist)한 상태
- 준영속(detached)
- 영속성 컨텍스트에 저장되었다가 분리된 상태
- 영속성 컨텍스트가 관리하던 영속 상태였던 엔티티를 더 이상 관리하지 않는 상태
- entitymanager.detach(), entitymanager.close(), entitymanager.clear()순을 통해 준영속 상태로 만들 수 있다.
- 삭제(deleted)
- 삭제된 상태
- 엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제한 상태
영속성 컨텍스트란?
- JPA를 이해하는데 가장 중요한 용어
- 엔티티를 영구 저장하는 환경
- EntityManager로 Entity를 저장하거나 조회하면 EntityManager는 영속성 컨텍스트에 Entity르 보관하고 관리한다.
세번째 그림에 대한 설명
- 영속성 컨텍스트 1차 캐시
- 영속성 컨텍스트는 내부에 캐시를 가지고 있는데, 이것을 1차 캐시라고 한다.
- 영속 상태의 엔티티는 모두 이곳에 저장되며, 구조로 설명하자면 이 안에 Map의 구조로 이해하면 된다.
- 그 Map의 Key 값에는 식별자 값이 있고 Value에는 그 해당 엔티티의 인스턴스가 있다.
- 1차 캐시에서 조회
- entitymanager.find()를 호출하게 되면, 먼저 1차 캐시에서 엔티티를 찾게 되고 이곳에 없다면 데이터베이스에서 조회한다.
- 1차 캐시에 없어 데이터베이스 조회
- 만약 1차 캐시에 없으면 데이터베이스에서 조회를 하게 된다.
- 그러면 데이터베이스에서 조회를 하여 엔티티를 우선 생성을 한다.
- 그리고 1차 캐시에 저장하여 영속 상태인 엔티티를 반환해준다.
- 그 결과, 영속성 컨텍스트는 엔티티의 동일성을 보장한다.
네번째 그림에 대한 설명
- 쓰기 지연, 회원 A 영속
- entitymanager.persist()함수를 호출하여 회원 A를 1차 캐시에 저장하고 쓰기지연 SQL 저장소에 보관한다.
- 쓰기지연 SQL 저장소라는 것은 트랜잭션을 커밋을 하기 전까지 쿼리문을 잠깐 보관하는 곳을 의미한다.
- 이러한 것을 영속환한다~라고 한다.
- 쓰기 지연, 회원 B 영속
- entitymanager.persist()함수를 호출하여 회원 B를 1차 캐시에 저장하고 쓰기지연 SQL 저장소에 보관한다.
- 이것 또한 영속화한다~라고 보면 되겠지요~?
- 그럼 2개의 쿼리가 쓰기 지연 SQL 저장소에 저장되어 있다.
- 쓰기 지연, 커밋
- 마지막으로 transaction.commit()함수를 호출한다.
- 그렇게 되면 엔티티 매니저는 우선 영속성 컨텍스트를 flush한다.
- flush란, 영속성 컨텍스트의 변경 내용을 데이터베이스와 동기화하는 작업이라고 생각하면 되고, 보통 CRUD된 엔티티를 반영한다.
- 이러한 과정을 통해 동기화 된 후에 실제 데이터베이스 트랜잭션을 커밋하게 된다.
다섯번째 그림에 대한 설명
- 변경감지
- 프로젝트의 규모가 커지면 수정에 관한 SQL문을 직적 작성하는 일이 많아지고 직접적이든, 간접적이든 비즈니스 로직이 SQL에 의존하게 되는 일이 생긴다.
- 그리하여 JPA로 엔티티를 수정하는 경우에는 단순히 엔티티를 조회해서 데이터만 변경하면 된다. 이렇게 변경된 사항을 자동으로 데이터베이스에 반영하는 기능을 변경감지하고 한다.
- JPA에서는 엔티티를 영속화할 때 최초 상태를 복사해서 저장해두는데 이것을 스냅샷이라고 한다. 그리고 플러시 시점에 스냅샷과 엔티티를 비교해서 변경된 엔티티를 찾는다.
- 그 과정 내에서 변경된 엔티티가 있으면 수정 쿼리를 생성하여 쓰기 지연 SQL 저장소에 보관하고, 보관한 SQL을 데이터베이스에 보내고 커밋하게 된다.
- detach 실행 전 & detach 실행 후
- detach 실행 전은 영속성 컨텍스트에 의해 관리되고 있다
- detach를 실행하고 나면 영속성 컨텍스트가 회원 A를 관리하지 않으며 변경사항이 데이터베이스에 반영되지 않는다.
- 이것을 영속 상태에서 더는 영속성 컨텍스트가 관리하지 않기 때문에 준영속 상태라고 한다.
여섯번째 그림에 대한 설명
- entitymanager.clear()를 통해 영속성 컨텍스트를 비울 수 있다. 이때는 아직 트랜잭션은 유효하므로 새로운 entity를 persist하거나 기존 엔티티를 merge할 수 있다.
- entitymanager.close()는 해당 영속성 컨텍스트 자체가 닫히며, 더 이상 EntityManager와 모든 상호작용이 불가능해진다.
728x90
반응형