이전 글과 이어져서 작성되는 글입니다.
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 가능하게 하기 (4) | 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 |