Skip to content

Commit

Permalink
feat : CQRS를 위한 @transactional(readOnly) 에 따른 Secondary DB 매핑 처리
Browse files Browse the repository at this point in the history
  • Loading branch information
vanillacake369 committed Feb 1, 2024
1 parent 60fe247 commit f848e5b
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 72 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package bc1.gream.global.config.datasource;


public class TransactionRoutingDataSource {
// extends AbstractRoutingDataSource {

// @Nullable
// @Override
// protected Object determineCurrentLookupKey() {
// return TransactionSynchronizationManager
// .isCurrentTransactionReadOnly() ?
// DataSourceType.READ_ONLY :
// DataSourceType.READ_WRITE;
// }
import jakarta.annotation.Nullable;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.transaction.support.TransactionSynchronizationManager;

public class TransactionRoutingDataSource
extends AbstractRoutingDataSource {

@Nullable
@Override
protected Object determineCurrentLookupKey() {
return TransactionSynchronizationManager
.isCurrentTransactionReadOnly() ?
DataSourceType.READ_ONLY :
DataSourceType.READ_WRITE;
}
}
Original file line number Diff line number Diff line change
@@ -1,52 +1,65 @@
package bc1.gream.global.config.datasource;

import com.zaxxer.hikari.HikariDataSource;
import jakarta.persistence.EntityManagerFactory;
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
public class TransactionRoutingDataSourceConfig {

// @ConfigurationProperties(prefix = "spring.datasource.hikari.primary")
// @Bean
// public DataSource primaryDataSource() {
// return DataSourceBuilder.create().type(HikariDataSource.class).build();
// }
//
// @ConfigurationProperties(prefix = "spring.datasource.hikari.secondary")
// @Bean
// public DataSource secondaryDataSource() {
// return DataSourceBuilder.create().type(HikariDataSource.class).build();
// }
//
// @DependsOn({"primaryDataSource", "secondaryDataSource"})
// @Bean
// public DataSource routingDataSource(
// @Qualifier("primaryDataSource") DataSource primary,
// @Qualifier("secondaryDataSource") DataSource secondary) throws SQLException {
// TransactionRoutingDataSource routingDataSource = new TransactionRoutingDataSource();
//
// Map<Object, Object> dataSourceMap = Map.of(
// DataSourceType.READ_WRITE, primary,
// DataSourceType.READ_ONLY, secondary
// );
//
// routingDataSource.setTargetDataSources(dataSourceMap);
// routingDataSource.setDefaultTargetDataSource(primary);
//
// return routingDataSource;
// }
//
// @DependsOn({"routingDataSource"})
// @Primary
// @Bean
// public DataSource dataSource(DataSource routingDataSource) {
// return new LazyConnectionDataSourceProxy(routingDataSource);
// }
//
// @Bean
// public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
// JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
// jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
// return jpaTransactionManager;
// }
@ConfigurationProperties(prefix = "spring.datasource.hikari.primary")
@Bean
public DataSource primaryDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}

@ConfigurationProperties(prefix = "spring.datasource.hikari.secondary")
@Bean
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}

@DependsOn({"primaryDataSource", "secondaryDataSource"})
@Bean
public DataSource routingDataSource(
@Qualifier("primaryDataSource") DataSource primary,
@Qualifier("secondaryDataSource") DataSource secondary) throws SQLException {
TransactionRoutingDataSource routingDataSource = new TransactionRoutingDataSource();

Map<Object, Object> dataSourceMap = Map.of(
DataSourceType.READ_WRITE, primary,
DataSourceType.READ_ONLY, secondary
);

routingDataSource.setTargetDataSources(dataSourceMap);
routingDataSource.setDefaultTargetDataSource(primary);

return routingDataSource;
}

@DependsOn({"routingDataSource"})
@Primary
@Bean
public DataSource dataSource(DataSource routingDataSource) {
return new LazyConnectionDataSourceProxy(routingDataSource);
}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
return jpaTransactionManager;
}
}
31 changes: 13 additions & 18 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
spring:
profiles:
active: prod
datasource:
url: jdbc:mysql://${DB_URL}/gream
username: ${DB_ID}
password: ${DB_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
# DATASOURCE
# datasource:
# hikari:
# primary:
# driver-class-name: com.mysql.cj.jdbc.Driver
# jdbc-url: jdbc:mysql://${DB_URL}/gream
# username: ${DB_ID}
# password: ${DB_PASSWORD}
# secondary:
# driver-class-name: com.mysql.cj.jdbc.Driver
# jdbc-url: jdbc:mysql://${DB_READ_ONLY_URL}/gream
# username: ${DB_ID}
# password: ${DB_PASSWORD}
# DATASOURCE
datasource:
hikari:
primary:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://${DB_URL}/gream
username: ${DB_ID}
password: ${DB_PASSWORD}
secondary:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://${DB_READ_ONLY_URL}/gream
username: ${DB_ID}
password: ${DB_PASSWORD}
# JPA
jpa:
hibernate:
Expand Down

0 comments on commit f848e5b

Please sign in to comment.