티스토리 뷰
JtaTransactionManager란?
JtaTransactionManager는 Spring에서 제공하는 JTA(Java Transaction API) 기반의 트랜잭션 매니저입니다. 분산 트랜잭션(distributed transaction)을 관리할 때 사용되며, 여러 개의 데이터 소스 또는 다른 트랜잭션 자원(예: JMS, JPA, JDBC)을 하나의 트랜잭션 내에서 처리할 수 있도록 지원합니다.
1. JTA와 JtaTransactionManager의 개념
1) JTA(Java Transaction API)란?
- 자바에서 트랜잭션을 관리하기 위한 표준 API입니다.
- XA(Extended Architecture) 프로토콜을 기반으로 동작하여 여러 개의 데이터베이스나 메시지 큐를 포함한 다중 자원에 대한 트랜잭션을 지원합니다.
- 대표적인 JTA 구현체로 Atomikos, Bitronix, Narayana(JBoss Transactions) 등이 있습니다.
2) JtaTransactionManager란?
- Spring에서 JTA 트랜잭션을 관리하기 위해 제공하는 추상화된 트랜잭션 매니저입니다.
- 여러 데이터베이스 또는 메시지 브로커(JMS 등) 간 일관된 트랜잭션을 보장합니다.
- 기본적으로 JTA 구현체(예: Atomikos, Bitronix, Narayana)와 함께 사용됩니다.
2. JtaTransactionManager의 특징
- 분산 트랜잭션 지원
- 단일 데이터베이스 트랜잭션이 아니라 여러 데이터베이스나 자원(JMS, JPA, JDBC 등) 을 하나의 트랜잭션으로 처리할 수 있습니다.
- XA 트랜잭션 지원
- XA(Extended Architecture) 기반으로 2단계 커밋(2PC, Two-Phase Commit)을 통해 데이터 일관성을 보장합니다.
- Spring과의 통합
- Spring의 @Transactional과 함께 사용할 수 있으며, Declarative(선언적) 트랜잭션 관리를 제공합니다.
- JTA 구현체 필요
- JtaTransactionManager는 자체적으로 트랜잭션을 처리하지 않고, Atomikos, Bitronix, Narayana 같은 외부 트랜잭션 매니저가 필요합니다.
3. JtaTransactionManager 설정 방법
1) 기본 설정 (Spring Boot + Atomikos)
Spring Boot에서 JtaTransactionManager를 설정하려면 Atomikos를 사용하는 방법이 일반적입니다.
(1) 의존성 추가
Gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-jta-atomikos'
implementation 'com.atomikos:transactions-jdbc:5.0.9'
implementation 'mysql:mysql-connector-java'
}
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jdbc</artifactId>
<version>5.0.9</version>
</dependency>
2) 데이터 소스 및 트랜잭션 매니저 설정
JTA를 사용하려면 XA 트랜잭션을 지원하는 데이터 소스를 설정해야 합니다.
import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.jta.JtaTransactionManager;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setUniqueResourceName("db1");
Properties properties = new Properties();
properties.setProperty("user", "root");
properties.setProperty("password", "password");
properties.setProperty("URL", "jdbc:mysql://localhost:3306/testdb");
properties.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
xaDataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
xaDataSource.setXaProperties(properties);
return xaDataSource;
}
@Bean
public JtaTransactionManager transactionManager() {
return new JtaTransactionManager();
}
}
설명
- AtomikosDataSourceBean을 사용하여 XA 지원 데이터 소스를 생성합니다.
- setXaDataSourceClassName()을 사용하여 XA 트랜잭션을 지원하는 데이터 소스를 설정합니다.
- JtaTransactionManager를 빈으로 등록하여 Spring에서 JTA 기반 트랜잭션을 사용할 수 있도록 합니다.
4. JtaTransactionManager 사용 방법
1) @Transactional을 활용한 트랜잭션 처리
Spring에서는 @Transactional을 사용하여 JTA 기반의 분산 트랜잭션을 처리할 수 있습니다.
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class TransactionalService {
private final UserRepository userRepository;
private final OrderRepository orderRepository;
public TransactionalService(UserRepository userRepository, OrderRepository orderRepository) {
this.userRepository = userRepository;
this.orderRepository = orderRepository;
}
@Transactional
public void createOrder() {
User user = new User("홍길동");
userRepository.save(user);
Order order = new Order("상품 A", user);
orderRepository.save(order);
// 예외 발생 시 모든 데이터베이스 작업이 롤백됨
if (order.getItem().equals("상품 A")) {
throw new RuntimeException("강제 예외 발생");
}
}
}
설명
- @Transactional을 사용하면 JTA 기반의 분산 트랜잭션이 자동으로 관리됩니다.
- UserRepository와 OrderRepository가 서로 다른 데이터베이스를 사용해도 한 트랜잭션 내에서 처리됩니다.
- 예외가 발생하면 모든 데이터베이스 변경 사항이 롤백됩니다.
5. JtaTransactionManager의 장점과 단점
1) 장점
- 분산 트랜잭션 지원: 여러 개의 데이터베이스 또는 메시지 브로커(JMS 등)를 하나의 트랜잭션으로 관리할 수 있습니다.
- Spring과 쉽게 통합 가능: @Transactional과 함께 사용하면 간단한 코드로 트랜잭션을 관리할 수 있습니다.
- XA 지원 데이터 소스를 활용 가능: MySQL, PostgreSQL, Oracle 등의 XA 지원 데이터 소스를 활용할 수 있습니다.
2) 단점
- 설정이 복잡함: XA 드라이버 및 JTA 트랜잭션 매니저를 별도로 설정해야 합니다.
- 성능 오버헤드 발생: XA 트랜잭션을 사용할 경우 2단계 커밋(2PC) 과정이 추가되므로 성능이 저하될 수 있습니다.
- Spring Boot 기본 트랜잭션 매니저보다 무거움: 일반적인 DataSourceTransactionManager보다 무겁고 관리 비용이 높습니다.