JPA에서 중요한 영속성 컨텍스트(Persistence Context)
엔티티 매니저(Entity Manager),
영속성 컨텍스트 타입(Persistence Context type)
영속성 컨텍스트(Persistence Context)의 장점
JPA는 객체지향과 DB간에 발생하는 차이를 메꿔줌
java application과 JDBC API 사이에 존재
JPA는 인터페이스의 모음이며 HIbernates는 그 구현체입니다
Entity는 DB 테이블과 매핑되는 객체
엔티티 매니저 팩터리와 엔티티 매니저(Entity Manager Factory & Entity Manager)
EntityManagerFactory entityManagerFactory는 Entity Manager를 만들고 구성하는 법을 제공하는 interface
jpa의 구현체인 hibernate나 eclipseLink에 의해 생성되며 entity Manager 인스턴스를 생성하는데 사용됨.
entityManager
엔티티매니저는 디비 테이블과 맵핑된 객체인 엔티티에 대한 CRUD 작업을 수행하기 위한 method들을 제공하며 entity의 라이프 사이클과 영속성 관리등을 담당합니다.
Persistence
oracleDocs 에서 설명하는 영속성 컨텍스트
- 영속성 컨텍스트는 영속화 되어 있는 entity identity에 대해 unique한 entity 인스턴스가 존재하는 entity 인스턴스의 집합이라고 되어있습니다.
영속성 컨텍스트는 즉 entity의 영속화에 관여하며
entity들이 db로 바로 가지 않고 entity를 저장하는 환경으로서의 역할을 함.
영속성 컨텍스트는 논리적인 개념이며 아래 코드와 같이 entityManager를 통해서 영속성 컨텍스트에 접근하게 됨
EntityManager.persist(entity);
EntityManager.persist() 를 활용하여 해당 entity를 영속성 컨텍스트로 보내고
영속성 컨텍스트를 통해 해당 데이터를 영속화 한다라는 의미입니다.
영속성 컨텍스트 타입은 무엇이 있을까요?
- Transactions-scope persistence context
- Extended-scope persistence context
두가지에 대해 알아봅시다.
Application
: Entity Manager1. <-> operation <-> persistence Context -> persist -> DB
: Entity Manager2 <-> operation <-> persistence Context -> persist-> DB
: Entity Manager3 <-> operation <-> persistence Context -> persist -> DB
Find <- DB
Find <- DB
Find <- DB
Transaction-scope persistence context는 transaction에 바이딩 됩니다. transaction이 완료되는 즉시 영속성 컨텍스트에 있는 entity들은 영구 스토리지 즉 DB로 flush 됩니다.
transaction 내부에서 작업을 수행할때 EntityManager는 영속성 컨텍스트가 하나라도 존재한다면 존재하는 것을 사용하며 하나라도 없다면 영속성 컨텍스트를 생성합니다.
Default persistence context type 은 transaction 입니다. EntityManager에게 영속성 컨텍스트를 사용하게 하기 위해 @PersistenceContext 어노테이션을 달아주면 됩니다.
Extended-scope persistence context는 영속성 컨텍스트가 multiple transacion에 걸쳐서 존재할 수 있습니다.
Transaction 없이 entity를 영속성 컨텍스트에 유지 시킬 수 는 있지만 transaction 없이 DB에 플러시 할 수 없습니다.
EntityManager에 @PersistenceContext 어노테이션에 type 값으로 PersistenceContextType.EXTENDED
를 명시해야 합니다.
@PersistenceContext(type = PersistenceContextType.EXTENDED)
Private EntityManager entityManager;
영속성 컨텍스트의 장점
영속성 컨텍스트는 데이터베이스와 애플리케이션 중간에 위치하며 중간에 위치함으로서, 또한 영속성 컨텍스트가 제공하는 기능 등을 통해 얻는 이점들이 존재합니다.
- 성능 향상
영속성 컨텍스트를 사용하면 엔티티를 메모리에 캐시함으로서 빈번하게 데이터베이스에 접근하는 것을 줄일 수 있고, 데이터 베이스 로드 또한 줄어듭니다.
- 간소화된 데이터베이스 엑세스
엔티티를 관리하기 위한 단순화된 api를 제공하여 데이터베이스 엑세스를 단순화합니다. 이를 통해 개발자는 낮은 수준의 데이터베이스 엑세스를 위한 쿼리에 집중하기 보다는 애플리케이션의 비즈니스 로직에 집중할 수 있습니다.
- 데이터 일관성의 향상
영속성 컨텍스트는 엔티티 라이프 사이클 즉 엔티티의 상태에 대한 관리를 자동적으로 관리함으로서 엔티티가 일관성 있도록 보장해줍니다.
- 향상된 scalability
영속성 컨텍스트는 데이터베이스에 대한 접근과 엔티티의 상태관리를 자동적으로 하기 때문에 확장성에서도 이점을 갖습니다.
========================================================================================
@PersistenceContext란?
- EntityManager를 빈으로 주입할때 사용하는 어노테이션
영속성 컨텍스트를 의미
그래서 스프링 컨테이너가 시작될때 EntityManager를 만들어서 빈으로 등록해둠
이때 스프링이 만들어둔 EntityManager를 주입받을때 사용합니다.
@PersistenceContext로 지정된 프로퍼티에 아래 두가지 중 한가지로 EntityManager를 주입해줍니다.
EntityManagerFacotry에서 새로운 EntityManager를 생성하거나
Transaction에 의해 기존에 생성된 EntityManager를 반환해줍니다.
@PersistenceContext를 사용해야 하는 이유
EntityManager를 사용할때 주의해야 할 점은 여러 쓰레드가 동시에 접근하면 동시성 문제가 발생하여 쓰레드 간에는 EntityManager를 공유해서는 안됩니다.
일반적으로 스프링은 싱글톤 기반으로 동작하기에 빈은 모든 쓰레드가 공유합니다.
그러나 @PersistencContext으로 EntityManager를 주입받아도 동시성 문제가 발생하지 않습니다.
동시성 문제가 발생하지 않는 이유는
스프링 컨테이너가 초기화되면서 @PersistenceContext으로 주입받은 EntityManager를 Proxy로 감쌉니다.
그리고 EntityManager 호출시마다 Proxy를 통해 EntityManager를 생성하여 Thread-safe를 보장합니다.
추후 정리 필요:
영속성 컨텍스트가 관리하는 엔티티의 생명주기
1차캐시
변경감지(dirty-check)
참조:
'Spring' 카테고리의 다른 글
SuperBuilder 란 (0) | 2024.07.08 |
---|---|
리플렉션 (0) | 2024.07.08 |
학습테스트 마무리 (0) | 2024.07.07 |
ATDD 1주차 (0) | 2024.07.04 |
Next Step 학습테스트를 통한 스프링 2주차 (0) | 2024.06.18 |