개요
- Java Persistence API ( JPA ) 의 일부이다.
- 컨테이너 관리형 영속성 컨텍스트에 대한 EntityManager 주입의 역할을 수행한다.
영속성 컨텍스트의 역할
- 엔티티 인스턴스의 생명주기를 관리한다.
- DB와 상호작용을 담당한다.
사용은 언제하나?
- DAO(서비스 레이어) 혹은 Repository 계층에서 사용한다.
해당 어노테이션 역할
- JPA 영속성 컨텍스트에 접근하기 위해 사용되는
EntityManager
를 주입받기 위해 사용된다.
- Spring Framework 에서 해당 어노테이션을 통해 컨테이너가 관리하는 EntityManager 를 Service 레이어 혹은 레포 레이어에 제공
이점
- 자원의 관리
- DB 연결을 효율적으로 ㄱㄴ
- 트랜잭션의 관리
- 트랜잭션 범위에서 영속성 컨텍스트를 제공한다.
- Thread Safe
- 컨테이너가 EntityManger 를 관리하여 스레드에 안전함
그럼 어디서 EntityManager 를 관리하는지 찾아보자
- 일단 SharedEntityManagerCreator.class 를 찾아보자
- 이는 Jpa 라이브러리의 일부로서..
- 관련 주제로 PersistenceContext 가 존재함으르 알 수 있다.
- 한글로 번역하니
- 즉, em 이 존재하는 경우 해당 em 을 사용하고, 존재하지 않는 경우 새로 생성된 em 을 사용함을 알 수 있다.
해당 클래스에서 EntityManager의 프록시 생성하는 곳은.
/**
* Create a transactional EntityManager proxy for the given EntityManagerFactory.
* @param emf the EntityManagerFactory to obtain EntityManagers from as needed
* @param properties the properties to be passed into the
* {@code createEntityManager} call (may be {@code null})
* @param synchronizedWithTransaction whether to automatically join ongoing
* transactions (according to the JPA 2.1 SynchronizationType rules)
* @param entityManagerInterfaces the interfaces to be implemented by the
* EntityManager. Allows the addition or specification of proprietary interfaces.
* @return a shareable transactional EntityManager proxy
* @since 4.0
*/
public static EntityManager createSharedEntityManager(EntityManagerFactory emf, @Nullable Map<?, ?> properties,
boolean synchronizedWithTransaction, Class<?>... entityManagerInterfaces) {
ClassLoader cl = null;
if (emf instanceof EntityManagerFactoryInfo) {
cl = ((EntityManagerFactoryInfo) emf).getBeanClassLoader();
}
Class<?>[] ifcs = new Class<?>[entityManagerInterfaces.length + 1];
System.arraycopy(entityManagerInterfaces, 0, ifcs, 0, entityManagerInterfaces.length);
ifcs[entityManagerInterfaces.length] = EntityManagerProxy.class;
return (EntityManager) Proxy.newProxyInstance(
(cl != null ? cl : SharedEntityManagerCreator.class.getClassLoader()),
ifcs, new SharedEntityManagerInvocationHandler(emf, properties, synchronizedWithTransaction));
}
- 요 부분이다.
SharedEntityManagerInvocationHandler
요 부분은 실제로 메서드 호출을 처리하는 내부 클래스로서,
TransactionSynchronizationManager
를 사용해 현재 스레드와 관련된 EM 를 찾고, 해당 EM 에 대한 모든 작업을 수행public abstract class TransactionSynchronizationManager { // ... private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal<>("Transactional resources"); public static Object getResource(Object key) { Object value = doGetResource(key); if (value != null && logger.isTraceEnabled()) { logger.trace("Retrieved value [" + value + "] for key [" + key + "] bound to thread [" + Thread.currentThread().getName() + "]"); } return value; } // ... }
- 각 스레드가 자신만의 EM 인스턴스를 가지고 작업하도록 보장.
- 해당 key 값을 조회하여 스레드내의 EM 존재여부를 파악하는 식으로 수행되는 것 같다.
- 각 스레드가 자신만의 EM 인스턴스를 가지고 작업하도록 보장.
Uploaded by N2T
'자바 > JPA' 카테고리의 다른 글
[JPA] em.persist 와 [repository.save](http://repository.save) 분석 (0) | 2024.02.24 |
---|---|
Jpa CascadeType 각 모드의 역할과 예시 코드 (0) | 2024.02.21 |
Jpa 에서 `@mappedBy` ? (0) | 2024.02.19 |
[JPA] 락 사용방법 및 종류 (0) | 2023.11.21 |
[JPA] 낙관적 락 옵션 (0) | 2023.11.21 |