이전 글과 이어져서 작성되는 글입니다.
https://cobbybb.tistory.com/25
@Transactional에 관한 고찰 (or 반성)
@Transactional..??? Spring이 알아서 해주잖아..? Spring + JPA 로 개발하다 보면 눈에 보이지 않는 것들에 대해서 놓치고 개발하는 경우가 빈번하게 생깁니다. 생각보다 많은 개념이 들어가 있는 @Transaction
cobbybb.tistory.com
TransactionManager와 EntityManager
이전 글에서 Spring에서 @Transactional
이 어떤 식으로 트랜잭션을 관리하는지에 TransactionManager
를 중심으로 알아보았습니다.
이번엔 spring에서 일반적으로 사용하는 JPA의 TransactionManager
는 어떻게 동작하는지 알아보려 합니다.
JPA의 TransactionManager
동작을 이해할때 가장 중요한것은 TransactionManager
내부에서의 EntityManager
동작을 이해하는것입니다.
AbstractPlatformTransactionManager
의 구현체 중 JPA를 사용할때 사용되는 JpaTransactionManager
의 내부 동작을 살펴보겠습니다.
JpaTransactionManager
JpaTransactionManager란?
이전 글에서 Spring내부에서의 Transaction관리는 AbstractPlatformTransactionManager
라는 추상화를 기준으로 한다는 것을 알 수 있었습니다.
그렇다면 JPA를 사용할 때도 그에 맞는 AbstractPlatformTransactionManager
가 있을 텐데 그것이 바로 JpaTransactionManager
입니다.
JpaTransactionManager의 의존성 EntityManagerFactory
JpaTransactionManager
의 코드를 열어보면 위 사진처럼 EntityManagerFactory
를 확인할 수 있습니다.
EntityManagerFactory의 출처
이 EntityManagerFactory
는 기본적으로 JpaBaseConfiguration.java
에서 bean으로 등록되어 주입됩니다.
(다만, @ConditionalOnMissingBean
이 있으니 별도의 EntityManagerFactory
를 구현해서 bean으로 등록했다면 해당 config는 동작하지 않습니다.)
JpaTransactionManager에서 EntityManagerFactory의 활용
JpaTransactionManager
에서 EntityManagerFactory
는 doBegin()
이 실행되는 순간부터 바로 활용되기 시작합니다.
doBegin()
내부로직을 보면 createEntityManagerForTransaction()
이라는 함수를 이용해서 EntityManger
를 반환받고 있는 것을 확인할 수 있습니다.
createEntityManagerForTransaction()
함수의 내부를 보면 드디어 EntityManagerFactory
를 이용해서 EntityManager
를 생성하는 구문을 발견할 수 있습니다. (위 그림 참고)
(이 코드 하나 확인하기 위해 길고 길었네요…)
그렇다면 Spring의 트랜잭션 관리 중 EntityManager
와 EntityManagerFactory
의 동작은 아래와 같이 중간 정리할 수 있습니다.
- Spring이 구동되면서
JpaBaseConfiguration
에 의해서EntityManagerFactory
가 singleton으로 Bean 등록됨 @Transactinoal
설정된 함수가 실행될 경우EntityManagerFactory
가EntityManager
를 생성- 생성된
EntityManager
를 이용하여 각각 Transaction을 관리
JpaTransactionManager 중 개발하는 입장에서 인지하고 있어야 할 내용
결국 개발하는 입장에서 인지하고 있어야할 내용은 2가지 입니다.
Transaction Context
(@Transactional
)와EntityManager
는 1:1 관계- 싱글톤으로 등록되어있는
EntityManagerFactory
가Transaction Context
이 생성될 때마다EntityManager
를 생성하는 구조
위 내용 중 @Transactional
을 Transaction Context라고 표현한 이유는 @Transactional
의 propagation 옵션이나 JPA Proxy이슈(이전 글 참고)로 인해서 @Transactional
: EntityManager
= 1 : 1 을 항상 유지하지는 않기 때문입니다.
TransactionInterceptor
다시 TransactionInterceptor란?
지금까지 TransactionManager
의 내부 동작에 관해 알아보았으니 TransactionManager
의 주 사용처인 TransactionInterceptor
의 내부 동작을 확인해봐야 합니다.
이전 글에서도 잠시 나왔지만 TransactionInterceptor
는 기본적으로 AOP advice
입니다.
즉, @Transactional
이 설정된 함수는 AOP가 동작하여 TransactionInterceptor
의 invoke()
함수로 실행되게 됩니다.
이후 실제로는 invokeWithTrasaction()
에 의해서 트랜잭션 관리 기능이 함께 실행되게 됩니다.
invokeWithTransaction()
invokeWithTrasaction()
로 실제 트랜잭션 관련 기능이 실행된다고 하는데 내부 내용을 살펴보겠습니다.
invokeWithTrasaction()
은 TransactionInterceptor
의 추상 클래스인 TransactionAspectSupport
에 있습니다.
위 실제 코드를 참고하면 아래와 설명과 같은 방식으로 비즈니스 로직 앞,뒤로 트랜잭션 관련 로직들이 실행되게 됩니다.
- 트랜잭션 생성
- 비즈니스 로직이 들어있는 함수 실행
- 이슈가 생겼다면 트랜잭션 종료 (
completeTransactionAfterThrowing
내부에 rollback 로직) - 정상 처리 되었다면 트랜잭션 commit 후 2번에서의 함수 실행 결과 return
정리하면 TransactionInterceptor
가 제공하는 advice 진입점과 invokeWithTrasaction()
의 트랜잭션 관리 기능을 통해서 개발자는 별다른 코드 없이 @Transactional
어노테이션 하나만으로 비즈니스 로직의 트랜잭션 관리가 가능해지게 됩니다.
Spring의 Transaction관리 총 정리
- Spring이 구동되면서
JpaBaseConfiguration
에 의해서EntityManagerFactory
가 singleton으로 Bean 등록됨 JpaTransactionManager
는 이EntityManagerFactory
를 주입받아EntityManager
를 생성하는 로직을 구현하여 실제 트랜잭션의 생성,종료에 해당하는 기능의 역할을 함TransactionInterceptor
는 AOP advice로서 비즈니스 로직의joinpoint
를 제공함- 또한
TransactionInterceptor
는 2번에서의JpaTransactionManager
를 주입받아
비즈니스 로직이 실행될 때 트랜잭션 관리에 맞는pointcut
로직을 실행함
'JPA' 카테고리의 다른 글
QueryDSL from절 Sub Query 가능하게 하기 (3) | 2023.03.20 |
---|---|
@Transactional에 관한 고찰 (or 반성) (0) | 2022.05.08 |
[JPA] 일반 Join과 Fetch Join의 차이 (8) | 2021.06.30 |
Proxy형태로 동작하는 JPA @Transactional (8) | 2021.02.10 |
[JPA] OneToOne 성능 튜닝 사례 1 (1) | 2020.08.18 |