[Day 27 | Spring] 다중 데이터베이스 연결 및 데이터 복제

y♡ding·2024년 11월 19일

데브코스 TIL - Spring

목록 보기
17/46

다중 데이터베이스 연결은 하나의 애플리케이션이 두 개 이상의 데이터베이스와 상호작용해야 할 때 사용됩니다. 주로 데이터 이동(백업/복제), 다중 시스템 연동, 또는 분산 데이터베이스 시스템에서 활용됩니다.


1. 개념 및 특징

1.1 다중 데이터베이스 연결

  • Spring Boot는 멀티 데이터 소스를 지원하며, 이를 설정하기 위해 DataSource 빈을 다중으로 정의하고 관리합니다.
  • 각각의 데이터 소스는 고유의 설정(properties)을 가집니다.
  • 각 데이터 소스를 기반으로 JdbcTemplate 또는 EntityManager를 생성하여 특정 데이터베이스와 작업을 수행합니다.

1.2 사용 사례

  1. 데이터 이동/복제
    • 기존 데이터베이스에서 다른 데이터베이스로 데이터 전송.
    • 주로 백업 또는 분산 환경에서 데이터 동기화.
  2. 이질적 데이터 연동
    • 서로 다른 스키마를 사용하는 두 데이터베이스 간 데이터 조작.
  3. 비즈니스 분리
    • 트랜잭션 또는 비즈니스 로직에 따라 서로 다른 데이터베이스를 활용.

2. 설정 및 실행 흐름

2.1 설정

(1) application.properties
# 데이터 소스 1 (sample)
spring.datasource1.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource1.jdbc-url=jdbc:mariadb://localhost:3306/sample
spring.datasource1.username=root
spring.datasource1.password=exxyeon

# 데이터 소스 2 (project)
spring.datasource2.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource2.jdbc-url=jdbc:mariadb://localhost:3306/project
spring.datasource2.username=root
spring.datasource2.password=exxyeon
(2) @Bean 설정
  • 각각의 데이터 소스를 Spring Bean으로 정의합니다.
@SpringBootApplication
public class Jjdbc03Application {

    @Bean
    @ConfigurationProperties("spring.datasource1")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource2")
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }

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

2.2 실행 흐름

  1. 데이터 소스 생성
    • DataSource 빈 두 개(dataSource1, dataSource2)를 생성.
    • 각각 sampleproject 데이터베이스와 연결.
  2. JdbcTemplate 생성
    • 각 데이터 소스를 기반으로 JdbcTemplate 생성.
    • 이를 통해 데이터베이스 쿼리 수행.
  3. 데이터 이동
    • 한 데이터베이스에서 데이터를 읽어와 다른 데이터베이스에 삽입.

3. 데이터 복제 구현

3.1 테이블 복제 준비

-- 복제 대상 데이터베이스로 이동
USE project;

-- source 테이블(dept)의 구조만 복사
CREATE TABLE dept AS SELECT * FROM sample.dept WHERE 1 != 1;

-- 복사된 테이블의 구조 확인
DESC dept;

-- 복사된 데이터 없는지 확인
SELECT COUNT(*) FROM dept;

3.2 코드 구현

(1) 데이터 전송 객체 정의
  • 데이터베이스의 데이터를 자바 객체로 매핑하기 위한 DTO 클래스 정의.
@Getter
@Setter
public class DeptTO {
    private String deptNo;
    private String dname;
    private String loc;
}
(2) 데이터 복제 로직(.update())
@Override
public void run(String... args) throws Exception {
    // 데이터 소스 출력
    System.out.println("dataSource1: " + dataSource1().getConnection());
    System.out.println("dataSource2: " + dataSource2().getConnection());

    // 데이터베이스별 JdbcTemplate 생성
    JdbcTemplate jdbcTemplate1 = new JdbcTemplate(dataSource1());
    JdbcTemplate jdbcTemplate2 = new JdbcTemplate(dataSource2());

    // 원본 데이터 조회 쿼리
    String selectSql = "SELECT * FROM dept";

    // 복사 대상 테이블에 삽입할 쿼리
    String insertSql = "INSERT INTO dept VALUES (?, ?, ?)";

    // 데이터베이스 1에서 데이터 조회
    List<DeptTO> results = jdbcTemplate1.query(
        selectSql,
        new BeanPropertyRowMapper<>(DeptTO.class)
    );

    // 데이터베이스 2로 데이터 복사
    for (DeptTO to : results) {
        System.out.println(to.getDeptNo());

        jdbcTemplate2.update(insertSql, to.getDeptNo(), to.getDname(), to.getLoc());
    }

    System.out.println("백업 완료");
}

4. 리팩토링 및 확장

4.1 데이터 유효성 검사

  • 데이터를 복제하기 전에 테이블 존재 여부 및 데이터 상태 확인.
// 테이블 존재 여부 확인
String tableCheckSql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = ?";
Integer count = jdbcTemplate2.queryForObject(
    tableCheckSql, Integer.class, "project", "dept");

if (count == 0) {
    System.out.println("테이블이 존재하지 않습니다.");
    return;
}

4.2 트랜잭션 처리

  • 데이터 이동 과정 중 실패 시 롤백하도록 트랜잭션 처리.
@Autowired
private PlatformTransactionManager transactionManager;

@Override
public void run(String... args) throws Exception {
    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());

    try {
        // 데이터 이동 로직 실행
        for (DeptTO to : results) {
            jdbcTemplate2.update(insertSql, to.getDeptNo(), to.getDname(), to.getLoc());
        }
        transactionManager.commit(status);
        System.out.println("백업 완료");
    } catch (Exception e) {
        transactionManager.rollback(status);
        e.printStackTrace();
    }
}

5. 정리

  1. 다중 데이터베이스 연결

    • Spring Boot의 DataSourceJdbcTemplate를 활용하여 두 개 이상의 데이터베이스와 독립적으로 작업 가능.
    • 각 데이터베이스에 대한 별도 설정 필요(application.properties@Bean).
  2. 데이터 복제

    • 원본 데이터베이스에서 데이터를 조회한 뒤, 대상 데이터베이스에 삽입.
    • 데이터베이스 간 데이터 일치와 무결성을 유지하는 데 활용.
  3. 확장성

    • 유효성 검사: 데이터 이동 전에 대상 테이블 구조와 상태 점검.
    • 트랜잭션 관리: 데이터 이동 중 오류 발생 시 롤백 처리.
    • 리팩토링: 중복된 데이터가 없는지 확인하거나, 필요한 데이터만 복사하는 로직 추가.
  4. 사용 사례

    • 데이터 백업: 주기적으로 데이터를 복사하여 백업 시스템 구축.
    • 데이터 동기화: 분산된 데이터베이스 환경에서 실시간 데이터 동기화.
    • 비즈니스 요구 대응: 다중 데이터베이스를 활용한 유연한 데이터 관리.

0개의 댓글