Spring Boot 다중 데이터 소스 및 트랜잭션 관리

Spring Boot 애플리케이션에서 여러 데이터베이스를 사용하고 각각의 트랜잭션을 제어하는 방법을 설명합니다.

애플리케이션 시작 지점에 @EnableTransactionManagement 어노테이션을 추가하여 트랜잭션 관리를 활성화합니다.

package com.example.multidb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication
@ComponentScan(basePackages={"com.example.multidb"})
@EnableCaching
@EnableTransactionManagement
public class MultiDatabaseApplication {

    public static void main(String[] args) {
        SpringApplication.run(MultiDatabaseApplication.class, args);
    }
}

application.properties 파일에 두 개의 데이터 소스 설정을 구성합니다.

# 첫 번째 데이터베이스 설정
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.primary.url=jdbc:mysql://192.168.18.221:3306/main_db?characterEncoding=utf8&useSSL=true
spring.datasource.primary.username=admin
spring.datasource.primary.password=admin123

# 두 번째 데이터베이스 설정
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.secondary.url=jdbc:mysql://192.168.18.221:3306/secondary_db?characterEncoding=utf8&useSSL=true
spring.datasource.secondary.username=admin
spring.datasource.secondary.password=admin123

Java 기반 설정 클래스를 생성하여 데이터 소스와 템플릿을 정의합니다. @Configuration 어노테이션을 적용하고 필요한 빈들을 구성합니다.

package com.example.multidb.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
public class DatabaseConfiguration {
    
    @Bean(name = "primaryDataSource")
    @Qualifier("primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource mainDataSource() {
        System.out.println("=== Primary DataSource 초기화 ===");
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondaryDataSource")
    @Qualifier("secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource additionalDataSource() {
        System.out.println("=== Secondary DataSource 초기화 ===");
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "primaryJdbcTemplate")
    public JdbcTemplate mainJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean(name = "secondaryJdbcTemplate")
    public JdbcTemplate additionalJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    
    // 트랜잭션 매니저 설정
    
    @Bean
    public PlatformTransactionManager primaryTxManager(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean
    public PlatformTransactionManager secondaryTxManager(@Qualifier("secondaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

서비스 계층에서 특정 데이터 소스의 트랜잭션을 사용하려면 다음과 같이 @Transactional 어노테이션을 적용합니다.

@Transactional(value = "secondaryTxManager", readOnly = true)
public Entity findById(Long id) {
    return repository.findById(id);
}

@Transactional(value = "secondaryTxManager")
public void updateRecord(String value) {
    repository.update(value);
    int result = 10 / 0; // 예외 발생 테스트
}

특정 데이터 소스의 JdbcTemplate이나 DataSource를 주입받고자 할 때는 @Qualifier 어노테이션을 사용합니다.

@Autowired
@Qualifier("secondaryJdbcTemplate")
private JdbcTemplate secondaryTemplate;

@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDs;
@Autowired
@Qualifier("primaryJdbcTemplate")
private JdbcTemplate primaryTemplate;

@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDs;

태그: spring-boot JDBC MySQL transaction-management database-configuration

6월 10일 00:34에 게시됨