diff --git a/src/main/java/fourservings_fiveservings/insurance_system_be/common/config/DataSourceConfig.java b/src/main/java/fourservings_fiveservings/insurance_system_be/common/config/DataSourceConfig.java new file mode 100644 index 0000000..6fe6135 --- /dev/null +++ b/src/main/java/fourservings_fiveservings/insurance_system_be/common/config/DataSourceConfig.java @@ -0,0 +1,60 @@ +package fourservings_fiveservings.insurance_system_be.common.config; + +import java.util.HashMap; +import javax.sql.DataSource; +import lombok.extern.slf4j.Slf4j; +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.Primary; +import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy; + +@Slf4j +@Configuration +public class DataSourceConfig { + + private static final String SOURCE_SERVER = "source"; + private static final String REPLICA_SERVER = "replica"; + + @Bean + @Qualifier(SOURCE_SERVER) + @ConfigurationProperties("spring.datasource.source") + public DataSource masterDataSource() { + log.info("source register"); + return DataSourceBuilder.create().build(); + } + + @Bean + @Qualifier(REPLICA_SERVER) + @ConfigurationProperties("spring.datasource.replica") + public DataSource replicaDataSource() { + log.info("replica register"); + return DataSourceBuilder.create().build(); + } + + @Bean + public DataSource routingDataSource(@Qualifier(SOURCE_SERVER) DataSource masterDataSource, + @Qualifier(REPLICA_SERVER) DataSource slaveDataSource) { + + RoutingDataSourceConfig routingDataSource = new RoutingDataSourceConfig(); + + HashMap dataSourceMap = new HashMap<>(); + dataSourceMap.put(SOURCE_SERVER, masterDataSource); + dataSourceMap.put(REPLICA_SERVER, slaveDataSource); + + routingDataSource.setTargetDataSources(dataSourceMap); + routingDataSource.setDefaultTargetDataSource(masterDataSource); + + return routingDataSource; + } + + @Bean + @Primary + public DataSource dataSource() { + DataSource determinedDataSource = routingDataSource(masterDataSource(), + replicaDataSource()); + return new LazyConnectionDataSourceProxy(determinedDataSource); + } +} \ No newline at end of file diff --git a/src/main/java/fourservings_fiveservings/insurance_system_be/common/config/RoutingDataSourceConfig.java b/src/main/java/fourservings_fiveservings/insurance_system_be/common/config/RoutingDataSourceConfig.java new file mode 100644 index 0000000..3ece34e --- /dev/null +++ b/src/main/java/fourservings_fiveservings/insurance_system_be/common/config/RoutingDataSourceConfig.java @@ -0,0 +1,19 @@ +package fourservings_fiveservings.insurance_system_be.common.config; + +import jakarta.annotation.Nullable; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; +import org.springframework.transaction.support.TransactionSynchronizationManager; + +@Slf4j +public class RoutingDataSourceConfig extends AbstractRoutingDataSource { + + @Nullable + @Override + protected Object determineCurrentLookupKey() { + String lookupKey = + TransactionSynchronizationManager.isCurrentTransactionReadOnly() ? "replica" : "master"; + log.info("Current DataSource is {}", lookupKey); + return lookupKey; + } +} \ No newline at end of file diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 9d1239f..7de2662 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -8,7 +8,14 @@ spring: show_sql: true datasource: - url: ${DB_URL} - driver-class-name: com.mysql.cj.jdbc.Driver - username: ${DB_USER_NAME} - password: ${DB_PASSWORD} + source: + jdbc-url: ${DB_URL} + driver-class-name: com.mysql.cj.jdbc.Driver + username: ${DB_USER_NAME} + password: ${DB_PASSWORD} + replica: + jdbc-url: ${READ_DB_URL} + driver-class-name: com.mysql.cj.jdbc.Driver + username: ${DB_USER_NAME} + password: ${DB_PASSWORD} +