본문 바로가기
Spring

Spring - JpaTransactionManager의 동작 원리

by 오늘부터개발시작 2023. 1. 9.

JpaTransactionManager

지난 포스팅에서는 TransactionManager에 대해서 알아보았다. 

 

Spring - TransactionManager란?

TransactionManager란? 문제점 Spring에서 사용할 수 있는 DB 접근 기술들에는 순수 JDBC, JPA, R2DBC, 등의 다양한 기술들이 있다. 그런데 각각의 기술들은 서로 다른 Transaction 처리 방법을 제공한다. 아래는

obv-cloud.com

오늘은 실무에서 가장 많이 사용되는 TransactionManager의 구현체인 JpaTransactionManager가 어떻게 동작하는지 살펴보도록 하겠다. 

 

시작하기에 앞서 알아 둬야할 것은 아래 예시처럼 TransactionManager는 트랙잭션의 ID 같은 정보들을 가지고 있는 TransactionStatus 객체를 파라미터로 사용하여 commit, rollback, 등을 처리한다는 것이다.

트랜잭션을 사용하기 위해서는 반드시 TransactionStatus가 필요하기 때문에, 트랜잭션 시작 로직의 최종 목표는 TransactionStatus 객체를 생성하는 것이라고 볼 수 있다. 이 점에 집중해서 살펴보길 바란다.

// transactionStatus를 파라미터로 넘기는 예시
transactionManager.rollback(transactionStatus);

 

 

트랜잭션 시작

  1. 트랜잭션을 시작하기 위해서 transactionManager.getTransaction() 호출
  2. 내부적으로 JpaTransactionManage의 doGetTransaction()이 호출됨
  3. TransactionSynchronizationManager의 ThreadLocal에서
    EntityManagerHolder을 꺼내서 있으면 JpaTransactionObject에 담기
  4. ConnectionHolder를 ThreadLocal에서 꺼내서 있으면 JpaTransactionObject에 담기
  5. JpaTransactionObject 반환

* newEntityManagerHolder flag가 있는 이유는 아마도 nested 트랜잭션이 있을 경우에 가장 외부 트랜잭션(물리 트랜잭션)이 종료 됐을 때 EntityManager 를 닫기 위한 것으로 보임 (틀릴 수도 있음)

 

JpaTransactionManager.java

 

반환 받은 JpaTransactionObject를 활용하여 트랙잭션 존재 여부를 확인하여 기존 트랜잭션을 반환하거나 새로운 트랜잭션을 생성한다.

  1. 트랜잭션 존재 여부 체크
  2. 만약 트랜잭션이 존재하면 handleExistingTransaction에서 TransactionStatus를 반환
  3. 없으면 새로운 트랜잭션 생성

* 트랜잭션이 존재하지 않는지 확인하는 방법은 JpaTransactionObject가 가지고 있는 EntitiyManagerHolder의 transactionActive 값이 true인지 확인하는 것이다.

 

AbstractPlatformTransactionManager.java

 

생성하는 프로세스는 트랜잭션의 Propagation 설정에 따라서 달라지는데, 보통 REQUIRED를 사용하기 때문에 트랜잭션이 없으면 새로 생성

 

AbstractPlatformTransactionManager.java

 

트랜잭션이 새로 생성되는 곳은 AbstractPlatformTransactionManager 의 doBegin() 을 JpaTransactionManager 에서 상속 받은 메소드이다. 여기서는 EntityManager와 Connection을 모두 생성해서 JpaTransactionObject 에도 담고, TransactionSynchronizationManager 의 ThreadLocal 에도 담게 된다.

 

먼저 EntityManager를 생성하는 부분을 살펴보자.

  1. EntityManager 를 생성
  2. JpaTransactionObject 에 담기
  3. 실제 EntitiyManager 의 트랜잭션을 실행
  4. EntitiyManagerHolder 에 있는 transactionActive 를 True로 설정한다.
  5. TransactionSynchronizationManager 의 ThreadLocal에 담기

 

 

 

Connection 생성하는 부분을 살펴보자.

  1. EntityManager 를 사용해서 Connection 을 생성
  2. TransactionSynchronizationManager 의 ThreadLocal에 담기

 

트랙잭션이 끝나면

  1. EntityManager 와 Connection은 TransactionSynchronizationManager 의 ThreadLocal 에서 제거됨
  2. EntityManager 는 close 됨
  3. Connection 도 release 돼서 커넥션풀로 돌아감

 

 

여기까지 JpaTransactionManager의 동작원리에 대해서 알아보았다.