1. 스프링 트랜잭션 AOP 동작 흐름
@Transactional어노테이션을 사용한 선언적 트랜잭션 관리(Declarative Transaction Management)의 전체 흐름에는 크게 3가지 요소가 등장한다. 트랜잭션 매니저, 트랜잭션 AOP 프록시, 트랜잭션 동기화 매니저가 이에 해당된다.
클라이언트 코드로부터 요청이 들어오면 트랜잭션 AOP 프록시가 트랜잭션 매니저를 획득하고, 트랜잭션을 시작하기 위해서 트랜잭션 매니저에게 요청한다. 트랜잭션 시작 요청 받은 트랜잭션 매니저는 데이터소스를 통해 커넥션을 받아오고 트랜잭션을 시작한다. 그리고, 트랜잭션 매니저는 트랜잭션이 시작된 커넥션을 동기화 매니저에 보관한다. 이후 트랜잭션이 종료되는 경우 트랜잭션 매니저는 트랜잭션 동기화 매니저에 보관한 커넥션을 가져와 트랜잭션을 종료하고 커넥션을 반환하거나 종료한다.
- 좀 더 자세히!
1. 트랜잭션 매니저 (Transaction Manager)
트랜잭션 매니저는 트랜잭션을 생성, 커밋 또는 롤백하는 책임을 가진 핵심 컴포넌트입니다.
Spring에서는 DataSourceTransactionManager나 JpaTransactionManager와 같은 다양한 트랜잭션 매니저가 제공됩니다. 이들은 각각 JDBC나 JPA와 관련된 트랜잭션을 관리합니다.
트랜잭션 매니저는 트랜잭션을 시작하고 커넥션을 얻어오며, 트랜잭션이 종료된 후 커넥션을 반환하거나 종료합니다.
2. 트랜잭션 AOP 프록시 (Transaction AOP Proxy)
Spring에서 트랜잭션은 AOP(Aspect-Oriented Programming) 기반으로 관리됩니다. AOP 프록시가 클라이언트 코드의 메서드 호출을 가로채고, 해당 메서드가 트랜잭션을 시작하도록 합니다.
@Transactional 어노테이션이 적용된 메서드를 호출하면 AOP 프록시가 이를 감지하고, 트랜잭션을 처리할 책임이 있는 트랜잭션 매니저를 호출하여 트랜잭션을 시작합니다.
트랜잭션이 끝나면 트랜잭션 AOP 프록시가 트랜잭션의 커밋 또는 롤백을 결정하고 트랜잭션 매니저를 통해 트랜잭션을 종료합니다.
3. 트랜잭션 동기화 매니저 (Transaction Synchronization Manager)
트랜잭션 동기화 매니저는 현재 스레드에 해당하는 트랜잭션 상태를 관리하는 컴포넌트입니다. 이는 트랜잭션의 커넥션을 스레드에 바인딩하고, 트랜잭션을 커밋하거나 롤백할 때 동기화된 상태를 유지하도록 돕습니다.
트랜잭션이 시작되면 트랜잭션 매니저가 커넥션을 트랜잭션 동기화 매니저에 보관합니다. 이 커넥션은 나중에 트랜잭션이 완료되었을 때 반환되거나 종료됩니다.
트랜잭션 흐름
클라이언트 요청: 클라이언트 코드가 메서드를 호출하면 트랜잭션 AOP 프록시가 이를 가로챕니다.
트랜잭션 시작: 트랜잭션 AOP 프록시는 트랜잭션 매니저를 획득하고, 트랜잭션을 시작하도록 요청합니다.
커넥션 얻기: 트랜잭션 매니저는 데이터소스에서 커넥션을 가져와 트랜잭션을 시작합니다.
트랜잭션 동기화: 트랜잭션 매니저는 커넥션을 트랜잭션 동기화 매니저에 보관합니다.
트랜잭션 종료: 트랜잭션이 종료되면 트랜잭션 AOP 프록시가 트랜잭션 커밋 또는 롤백을 처리하고, 트랜잭션 동기화 매니저에서 커넥션을 반환합니다.
2. 트랜잭션 매니저와 트랜잭션 동기화 매니저는 무엇인가?
JDBC를 사용한 트랜잭션 관리 코드와 JPA를 사용한 트랜잭션의 양상이 다르다. 스프링은 개발자가 트랜잭션에 대한 구현 세부 사항을 신경 쓰지 않도록 트랜잭션 추상화인 PlatformTransactionManager를 제공한다. 개발자는 상황에 맞게 DataSourceTransactionManager, JpaTransactionManager를 사용할 수 있으며, 이를 트랜잭션 매니저(Transaction Manager) 라고 부른다.
서비스 로직에서 여러 서비스 로직을 호출할 수 있고, 데이터 접근 로직을 호출할 수도 있다. 이때 트랜잭션을 유지하기 위해서는 해당 트랜잭션을 시작한 커넥션이 여러 코드에 걸쳐 필요하게 된다. 트랜잭션 동기화 매니저(Transaction Syncronization Manager) 는 이를 도와준다. 만약, 트랜잭션 동기화 매니저가 없다면, 다른 코드의 메서드를 호출할 때마다 커넥션을 인자로 넘겨줘야 하는 문제가 발생한다.
- 좀더 자세히!
트랜잭션 추상화와 PlatformTransactionManager
Spring은 PlatformTransactionManager 인터페이스를 제공하여 트랜잭션 관리의 추상화 계층을 구현합니다. 이 인터페이스는 다양한 데이터 접근 기술에 맞게 구현될 수 있습니다. 예를 들어:
JDBC에서는 DataSourceTransactionManager를 사용하여 트랜잭션을 관리하고,
JPA에서는 JpaTransactionManager를 사용하여 트랜잭션을 관리합니다.
따라서, 데이터 접근 기술에 따라 적합한 트랜잭션 매니저를 선택하여 사용할 수 있습니다.
트랜잭션 동기화 매니저 (Transaction Synchronization Manager)
트랜잭션 동기화 매니저는 트랜잭션이 시작된 이후, 다른 메서드나 서비스 호출을 통해 트랜잭션을 동기화하는 역할을 합니다. 이를 통해 트랜잭션 커넥션이 여러 서비스 계층을 넘어 유지될 수 있습니다.
왜 트랜잭션 동기화가 필요할까?
트랜잭션을 시작한 후 여러 코드에서 동일한 커넥션을 사용하려면, 트랜잭션이 시작된 커넥션을 각 메서드나 서비스에 전달해야 합니다. 예를 들어, 하나의 서비스에서 다른 서비스 또는 데이터 접근 로직을 호출할 때마다 커넥션을 전달해야 하는 문제가 발생합니다. 이를 해결하는 것이 바로 트랜잭션 동기화 매니저입니다.
트랜잭션 동기화 매니저는 현재 실행 중인 스레드와 관련된 트랜잭션을 동기화시켜, 동일한 커넥션을 여러 메서드나 서비스에서 공유하도록 합니다. 즉, 커넥션을 명시적으로 전달할 필요 없이 Spring이 트랜잭션을 자동으로 관리하고 동기화합니다.
트랜잭션 흐름
트랜잭션 시작: 트랜잭션 AOP 프록시가 트랜잭션 매니저를 통해 트랜잭션을 시작합니다. 트랜잭션 매니저는 데이터베이스 커넥션을 가져오고 이를 트랜잭션 동기화 매니저에 등록합니다.
서비스 호출: 이후 여러 서비스나 데이터 접근 메서드를 호출할 때, 트랜잭션 동기화 매니저가 동일한 트랜잭션에 대한 커넥션을 관리하여 각 호출에 커넥션을 전달할 필요 없이 트랜잭션이 유지됩니다.
트랜잭션 종료: 트랜잭션이 끝나면, 트랜잭션 매니저는 동기화 매니저에서 커넥션을 가져와 트랜잭션을 커밋하거나 롤백한 후 커넥션을 반환합니다.
트랜잭션 동기화 매니저의 역할
트랜잭션을 시작하고 커넥션을 트랜잭션 동기화 매니저에 등록합니다.
트랜잭션이 종료될 때 커넥션을 자동으로 반환하거나 종료합니다.
트랜잭션 동기화 매니저는 커넥션을 현재 스레드와 연결시켜 다른 서비스에서 커넥션을 사용할 수 있도록 합니다.
예시 코드(JDBC 기반)
@Transactional
public void processTransaction() {
// 트랜잭션이 시작되고, 커넥션이 동기화 매니저에 등록됩니다.
serviceA(); // 다른 서비스 호출
serviceB(); // 또 다른 서비스 호출
// 트랜잭션이 종료되면 커넥션을 반환하거나 종료됩니다.
}
예시 코드(JPA 기반)
@Transactional
public void processTransaction() {
// JPA 트랜잭션 매니저가 트랜잭션을 시작하고 커넥션을 관리합니다.
serviceA(); // 다른 서비스 호출
serviceB(); // 또 다른 서비스 호출
// 트랜잭션이 종료되면 커넥션을 반환하거나 종료됩니다.
}
요약
**PlatformTransactionManager**는 트랜잭션 관리의 추상화 계층으로, JDBC나 JPA와 같은 데이터 접근 기술에 맞는 트랜잭션 매니저를 선택해 사용할 수 있습니다.
트랜잭션 동기화 매니저는 트랜잭션을 시작한 후 다른 서비스나 메서드가 동일한 커넥션을 사용할 수 있도록 도와줍니다.
트랜잭션이 시작되고 종료될 때 커넥션을 자동으로 관리해주기 때문에, 개발자는 트랜잭션을 관리하는 데 필요한 세부 구현을 신경 쓸 필요가 없습니다.
이러한 Spring의 트랜잭션 관리 시스템을 통해 개발자는 트랜잭션을 효율적으로 처리하면서도, 코드의 복잡성을 줄일 수 있습니다.
'개발 > Java & Kotlin' 카테고리의 다른 글
[Spring] 스프링 트랜잭션 전파 속성 (38) | 2025.03.29 |
---|---|
[Spring] CQRS 패턴이란? (97) | 2025.03.23 |
[Kotlin] 코틀린 + 스프링부트로 단숨에 완성하는 초강력 JWT 인증 시스템!💡 보안과 성능을 모두 잡아라!🔥(2) (40) | 2025.01.20 |
[Kotlin] 코틀린 + 스프링부트로 단숨에 완성하는 초강력 JWT 인증 시스템!💡 보안과 성능을 모두 잡아라!🔥 (54) | 2025.01.16 |
[Spring] 동기, 비동기 차이 (70) | 2024.12.31 |