본문 바로가기

Study Information Technology

Spring Boot와 JTA를 이용한 분산 트랜잭션 구현

728x90
반응형

Spring Boot와 JTA를 이용한 분산 트랜잭션 구현

Overview

분산 트랜잭션(distributed transaction)은 서로 다른 데이터베이스 또는 서비스가 포함된 트랜잭션을 관리하는 기법입니다. Spring Boot와 Java Transaction API (JTA)를 사용하여 이러한 트랜잭션을 구현하면, 여러 시스템 간의 데이터 일관성을 보장할 수 있습니다. 분산 트랜잭션은 특히 마이크로서비스 아키텍처를 사용할 때 중요합니다. 여기서는 Spring Boot 애플리케이션에서 JTA를 사용하여 분산 트랜잭션을 구현하는 방법에 대해 자세히 설명하겠습니다.

1. 분산 트랜잭션의 기본 개념

분산 트랜잭션은 여러 데이터베이스나 서비스에 걸쳐 있는 트랜잭션을 말합니다. 이를 관리하기 위해서는 두 가지 주요 개념이 있습니다:

  • 2단계 커밋(2PC, Two-Phase Commit): 트랜잭션의 모든 참여자(데이터베이스 등)가 작업을 커밋할 준비가 되었는지 확인한 후 실제로 커밋을 수행하는 방식입니다. 첫 번째 단계에서는 트랜잭션의 준비 상태를 확인하고, 두 번째 단계에서는 모든 참여자가 트랜잭션을 커밋하거나 롤백합니다.

  • JTA(Java Transaction API): 자바에서 분산 트랜잭션을 처리하기 위한 표준 API입니다. JTA는 트랜잭션 관리자와 자원 관리자의 인터페이스를 제공하여, 여러 데이터베이스와 서비스 간의 트랜잭션을 조정합니다.

2. Spring Boot에서 JTA를 사용하는 방법

Spring Boot에서는 JTA를 통해 분산 트랜잭션을 쉽게 처리할 수 있습니다. 여기서는 Atomikos라는 JTA 구현체를 사용하여 분산 트랜잭션을 설정하는 방법을 설명하겠습니다. Atomikos는 오픈소스 트랜잭션 관리자이며, JTA를 기반으로 합니다.

2.1. 의존성 추가

먼저, pom.xml 파일에 Atomikos와 관련된 의존성을 추가해야 합니다. Atomikos는 Spring Boot와의 통합을 위한 라이브러리를 제공합니다.

<dependencies>
  <!-- Spring Boot Starter Data JPA -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>

  <!-- Atomikos JTA -->
  <dependency>
    <groupId>com.atomikos</groupId>
    <artifactId>transactions-jta-api</artifactId>
    <version>5.0.8</version>
  </dependency>

  <!-- Atomikos Spring Integration -->
  <dependency>
    <groupId>com.atomikos</groupId>
    <artifactId>transactions-spring</artifactId>
    <version>5.0.8</version>
  </dependency>

  <!-- JDBC Driver for the databases you use -->
  <!-- Example for H2 database -->
  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
  </dependency>
</dependencies>

2.2. 설정 파일 작성

application.properties 또는 application.yml에 Atomikos 트랜잭션 관리자와 데이터베이스 설정을 추가합니다.

application.properties 예시:

# JTA Transaction Manager
spring.jta.atomikos.connectionFactory.xa-connection-factory=your-connection-factory
spring.jta.atomikos.datasource.xa-datasource=your-datasource

# DataSource settings
spring.jta.atomikos.datasource.your-datasource.unique-resource-name=your-database
spring.jta.atomikos.datasource.your-datasource.xa-datasource-class-name=org.h2.jdbcx.JdbcDataSource
spring.jta.atomikos.datasource.your-datasource.xa-datasource-url=jdbc:h2:mem:testdb
spring.jta.atomikos.datasource.your-datasource.xa-datasource-user=sa
spring.jta.atomikos.datasource.your-datasource.xa-datasource-password=sa

2.3. 트랜잭션 관리자 설정

Spring Boot에서 Atomikos를 트랜잭션 관리자로 사용하려면, Java Config 클래스를 작성하여 설정을 추가합니다.

import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.jta.JtaTransactionManager;

import javax.sql.DataSource;

@Configuration
public class JtaConfig {

@Bean
public DataSource dataSource() {
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
dataSource.setUniqueResourceName("myDataSource");
dataSource.setXaDataSourceClassName("org.h2.jdbcx.JdbcDataSource");
dataSource.setXaDataSourceUrl("jdbc:h2:mem:testdb");
dataSource.setUser("sa");
dataSource.setPassword("sa");
return dataSource;
}

@Bean
public PlatformTransactionManager transactionManager() {
return new JtaTransactionManager();
}
}

2.4. 트랜잭션 사용하기

서비스 클래스에서 @Transactional 어노테이션을 사용하여 분산 트랜잭션을 적용할 수 있습니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyService {

@Autowired
private MyRepository myRepository;

@Transactional
public void performTransaction() {
// 데이터베이스 작업
myRepository.save(new MyEntity("Test"));
// 다른 데이터베이스 작업
}
}

3. 에러 처리

JTA를 사용할 때 발생할 수 있는 일반적인 에러와 해결 방법은 다음과 같습니다:

3.1. XAException 발생

문제: 트랜잭션 관리자가 XA 트랜잭션을 처리하는 중 문제가 발생할 수 있습니다.

해결 방법:

  • 로그를 통해 문제의 원인을 파악합니다.
  • 데이터베이스와 트랜잭션 설정을 다시 확인합니다.
  • 필요시, 데이터베이스의 XA 드라이버와 설정이 올바르게 되어 있는지 확인합니다.

3.2. javax.transaction.RollbackException

문제: 트랜잭션 커밋 과정에서 롤백이 발생했습니다.

해결 방법:

  • 롤백 원인을 파악하기 위해 로그를 확인합니다.
  • 서비스 로직에서 트랜잭션 범위를 확인하고, 예외 처리를 올바르게 설정합니다.

참고문서

이 문서에서는 Spring Boot와 JTA를 사용하여 분산 트랜잭션을 설정하고 관리하는 방법을 자세히 설명했습니다. 각 단계별로 설정과 코드 예제를 통해 구현 방법을 안내하며, 발생할 수 있는 문제와 해결 방법도 함께 제공했습니다.

728x90
반응형