☁️ JPA 인터페이스
- EntityManagerFactory
- EntityManager
- Persistence Context
관련 정보를 찾다가 이해에 도움이 될 찰떡같은 비유가 있어서 해당 블로그 사진을 참조한다.
🫧 EntityManagerFactory
JPA 설정을 기반으로 EntityManager 인스턴스를 생성하는 팩토리 역할 (여러 EntityManager 생성 가능)
애플리케이션이 DB를 하나만 사용하는 경우 EntityManagerFactory 인스턴스를 한 번만 생성하고 재사용
🤔 여러 개의 DB를 사용하는 경우에는 EntityManagerFactory 인스턴스를 어떻게 다룰까?
1. 단일 EntityManagerFactory 인스턴스 사용
여러 DB를 사용하더라도, 모든 DB의 설정이 동일하다면 하나의 EntityManagerFactory 인스턴스를 생성하고 재사용할 수 있다.
2. 다중 EntityManagerFactory 인스턴스 사용
각각의 DB가 다른 설정을 가지고 있다면, 각 DB마다 별도의 EntityManagerFactory 인스턴스를 생성할 수 있다.
따라서 각 EntityManagerFactory 인스턴스는 해당하는 DB와의 연결을 관리하고, 애플리케이션 내에서 필요한 DB에 대한 EntityManager를 생성하여 사용한다.
여러 스레드 간 공유 가능하며 thread-safe 함
🫧 EntityManager
필요할 때마다 Entity Manager Factory에서 Entity Manager 생성
트랜잭션 범위 내에서 엔티티의 생명주기를 관리하고 데이터베이스와의 상호작용 처리
thread-safe 하지 않아 일반적으로 스레드당 하나의 EntityManager 사용
🧐 왜 thread-safe 하지 않을까?
- 한 스레드에서 시작한 트랜잭션에 여러 스레드가 커밋하고 롤백하는 작업은 오류 발생 가능성 높음
- EntityManager 인스턴스는 자체의 영속성 컨텍스트를 유지하는데 여러 스레드에서 동일 엔티티를 수정할 경우 데이터 충돌이 발생할 수 있음
❗️ Spring 환경에서 생성자를 통해 주입된 EntityManager는 싱글톤인데 동시성 문제가 발생하지 않나요??
→ 레포지토리 및 Config 파일에서 @Autowired 혹은 @PersistenceContext를 통해 주입받은 엔티티 매니저는 프록시 객체(가짜 객체)이고 이 엔티티 매니저를 호출할 때, 현재 DB 트랜잭션과 관련된 실제 엔티티 매니저 호출
❗️ 멀티 스레드 환경에서 같은 EntityManager를 사용하면 Persistence Context는 어떻게 되는건가요?
스프링 컨테이너는 스레드마다 다른 트랜잭션을 할당하기 때문에 같은 엔티티 매니저를 호출해도 접근하는 영속성 컨텍스트가 다름
→ 멀티스레드 상황에 안전
🫧 Persistence Context
영속성 컨텍스트는 JPA provider(ex. Hibernate, EclipseLink)에 의해 구현되며
일반적으로 개발자가 직접 조작하지 않고 자동으로 관리됨
EntityManager로 엔티티를 저장하거나 조회하면 EntityManager는 영속성 컨텍스트에 엔티티를 보관하고 관리
간단하게 엔티티를 사용하고 바로 폐기하는 것이 아니라 캐싱해 지속적으로 사용하며 이점을 얻음
- 엔티티 인스턴스의 생명주기 관리, 엔티티와 DB간의 상호 작용 중계 역할
- 엔티티를 캐싱해 같은 엔티티를 여러 번 로드하지 않도록 해 DB와의 불필요한 상호작용을 줄이고 성능 향상시킴
- 엔티티의 변경사항을 감지하고 트랜잭션을 커밋할 때 변경사항을 DB에 자동으로 반영
- 연관된 엔티티를 지연 로딩하여 필요한 시점에 DB에서 가져와 성능을 향상시키며 불필요한 DB 쿼리 방지
- 같은 엔티티 식별자(ID)를 가진 엔티티가 동일한 Java 객체로 표현되도록 보장해 동일한 엔티티에 대한 여러 조회가 항상 같은 객체 반환
🤭 영속성 컨텍스트에 더 자세히 알아보려면?
☁️ JPA의 구현체인 Hibernate
Hibernate는 위에 언급된 인터페이스를 직접 구현한 라이브러리
위 사진처럼 JPA의 핵심 인터페이스들을 Hibernate에서는 인터페이스로 상속받아 각각 Impl로 구현하고 있음
☁️ Spring Data JPA
Spring 프레임워크와 JPA를 통합하여 개발자들이 DB 액세스를 더 쉽게 할 수 있도록 도와주는 Spring 모듈
해당 모듈로 개발자들이 직접 EntityManager을 직접 다루지 않아도 됨
- CRUD 처리를 위한 공통 인터페이스 제공
- Repository 개발 시 인터페이스만 작성하면 실행 시점에 Spring Data JPA가 구현 객체를 동적으로 생성해 주입
- Spring Data JPA가 제공하는 공통 메서드를 통해 간편하게 데이터 접근 가능
'Back-end' 카테고리의 다른 글
[JPA] Hibernate Cache란? (0) | 2023.09.03 |
---|---|
[Spring] @Transaction(readOnly = true) 설정 (0) | 2023.09.01 |
[CI/CD] GitHub Actions를 이용한 빌드 및 배포 자동화 (0) | 2023.08.10 |
[Java] 가비지 컬렉션(Garbage Collection: GC) (0) | 2023.06.04 |
[Spring Boot] OAuth 2.0 를 이용한 소셜 로그인 구현 (0) | 2023.05.22 |