본문 바로가기
스프링/JPA

다중 DBconnection (with JPA)

by 공부 안하고 싶은 사람 2021. 2. 27.
반응형

다중 DB (with JPA)

https://jogeum.net/2?category=763774

 

 

DB에 맞는 의존성 추가

 

DB 정보 설정 (application.properties)

spring.datasource.postman.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.postman.jdbc-url=jdbc:oracle:thin:@host1:port:database
spring.datasource.postman.username=
spring.datasource.postman.password=

spring.datasource.postman-admin.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.postman-admin.jdbc-url=jdbc:oracle:thin:@host2:port:database
spring.datasource.postman-admin.username=
spring.datasource.postman-admin.password=

spring.datasource.h2.driver-class-name=org.h2.Driver
spring.datasource.h2.jdbc-url=jdbc:h2:mem:testdb;MODE=oracle;
spring.datasource.h2.username=sa
spring.datasource.h2.password=sa

 

 

설정값 객체로 등록

@Configuration
@EnableConfigurationProperties
public class DataSourceProperties {
    @Primary
    @Bean(name = "postmanDataSource")
    @Qualifier("postmanDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.postman")
    public HikariDataSource postmanDataSource() { return new HikariDataSource(); }

    @Bean(name ="postmanAdminDataSource")
    @Qualifier("postmanAdminDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.postman-admin")
    public HikariDataSource postmanAdminDataSource(){ return new HikariDataSource(); }

    @Bean(name ="H2DataSource")
    @Qualifier("H2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.h2")
    public HikariDataSource H2DataSource()
    {
        return new HikariDataSource();
    }
}

 

각 DB의 DataSource생성

 

 

entityManagerFactory - Entitiy 위치, .yml 설정된 DatasourceConfig
JpaTransactionManager <- entityManagerFactory 주입
EnableJpaRepositories - Repository 위치
NamedParameterJdbcTemplate - JdbcTemplate 설정

 

 

하나는 @Primary로 지정

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "postmanEntityManagerFactory",
        transactionManagerRef = "postmanTransactionManager",
        basePackages = {"humuson.tas.backend.repository.postman"})
public class PostmanDBConfig {
    @Autowired
    @Qualifier("postmanDataSource")
    private HikariDataSource postmanDataSource;

    @Primary
    @Bean(name = "postmanEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean postmanEntityManagerFactory(EntityManagerFactoryBuilder builder)
    {
        return builder.dataSource(postmanDataSource).persistenceUnit("postmanEntityManager").packages("humuson.tas.backend.domain.postman").build();
    }

    @Primary
    @Bean("postmanTransactionManager")
    public PlatformTransactionManager postmanTransactionManager(EntityManagerFactoryBuilder builder)
    {
        return new JpaTransactionManager(postmanEntityManagerFactory(builder).getObject());
    }

    @Primary
    @Bean(name = "postmanNamedParameterJdbcTemplate")
    public NamedParameterJdbcTemplate postmanNamedParameterJdbcTemplate(@Qualifier("postmanDataSource") HikariDataSource ds) {
        return new NamedParameterJdbcTemplate(ds);
    }
}

 

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "H2EntityManagerFactory",
        transactionManagerRef = "H2TransactionManager",
        basePackages = {"humuson.tas.backend.repository.h2"})
public class H2DBConfig {
    @Autowired
    @Qualifier("H2DataSource")
    private HikariDataSource H2DataSource;

    @Bean(name = "H2EntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean H2EntityManagerFactory(EntityManagerFactoryBuilder builder)
    {
        return builder.dataSource(H2DataSource).persistenceUnit("H2TransactionManager").packages("humuson.tas.backend.domain.h2").build();
    }

    @Bean("H2TransactionManager")
    public PlatformTransactionManager H2TransactionManager(EntityManagerFactoryBuilder builder)
    {
        return new JpaTransactionManager(H2EntityManagerFactory(builder).getObject());
    }

    @Bean(name = "H2NamedParameterJdbcTemplate")
    public NamedParameterJdbcTemplate H2NamedParameterJdbcTemplate(@Qualifier("H2DataSource") HikariDataSource ds) {
        return new NamedParameterJdbcTemplate(ds);
    }
}

 

 

 

트랜잭션의 어려움

  • @Transactional 안에 2가지 connection이 존재한다면, @Primary의 TransactionManager만 실행된다.
  • 하지만 별도로 Connection을 관리하기엔 코드가 복잡해짐
  • 따라서, 다중 트랜잭션 편리하게 처리하기 위해 ChainedTransactionManager 존재
    내부적으로 TransactionManager를 List에 담아 순차적으로 트랜잭션 처리한다
  • TransactionManager들을 주입받아서 ChainedTransactionManager 생성
    하나의 @Primary 필요
  • @Bean(name = "PostmanChainedTransactionManager") @Primary public PlatformTransactionManager transactionManager(@Qualifier("PostmanPlatformTransactionManager") PlatformTransactionManager txManager1, @Qualifier("PostmanAdminPlatformTransactionManager") PlatformTransactionManager txManager2) { return new ChainedTransactionManager(txManager1, txManager2); }
728x90
반응형

'스프링 > JPA' 카테고리의 다른 글

JPA 상속 관계 (TABLE_PER_CLASS전략)  (0) 2021.05.21
JPA 활용 1  (0) 2021.04.23
JPA 활용 2  (0) 2021.04.23
자바 ORM 표준 JPA  (0) 2021.04.16
스프링-입문-스프링부트 + JPA  (0) 2021.04.16

댓글