Skip to content

Commit

Permalink
DB replication ์ ์šฉ (#636)
Browse files Browse the repository at this point in the history
* feat: Replication ๊ธฐ๋Šฅ ์ถ”๊ฐ€

* feat: ์„œ๋ฒ„ datasource ์ถ”๊ฐ€
  • Loading branch information
cookienc authored Nov 17, 2023
1 parent 0cbb092 commit 3f9b9a5
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
2 changes: 1 addition & 1 deletion backend/baton/secret
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package touch.baton.config;

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.context.annotation.Profile;
import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;
import touch.baton.infra.database.datasource.DataSourceType;
import touch.baton.infra.database.datasource.RoutingDataSource;

import javax.sql.DataSource;
import java.util.Map;

import static touch.baton.infra.database.datasource.DataSourceType.Name.REPLICA_NAME;
import static touch.baton.infra.database.datasource.DataSourceType.Name.ROUTING_NAME;
import static touch.baton.infra.database.datasource.DataSourceType.Name.SOURCE_NAME;

@Profile("deploy")
@Configuration
public class DataSourceConfig {

@Qualifier(SOURCE_NAME)
@ConfigurationProperties(prefix = "spring.datasource.source")
@Bean
public DataSource sourceDataSource() {
return DataSourceBuilder.create().build();
}

@Qualifier(REPLICA_NAME)
@ConfigurationProperties(prefix = "spring.datasource.replica")
@Bean
public DataSource replicaDataSource() {
return DataSourceBuilder.create().build();
}

@Qualifier(ROUTING_NAME)
@Bean
public DataSource routingDataSource(@Qualifier(SOURCE_NAME) final DataSource sourceDataSource,
@Qualifier(REPLICA_NAME) final DataSource replicaDataSource
) {
return RoutingDataSource.createDefaultSetting(
Map.of(DataSourceType.SOURCE, sourceDataSource,
DataSourceType.REPLICA, replicaDataSource)
);
}

@Bean
@Primary
public DataSource dataSource(@Qualifier(ROUTING_NAME) final DataSource replicationRoutingDataSource) {
return new LazyConnectionDataSourceProxy(replicationRoutingDataSource);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package touch.baton.infra.database.datasource;

import static touch.baton.infra.database.datasource.DataSourceType.Name.REPLICA_NAME;
import static touch.baton.infra.database.datasource.DataSourceType.Name.SOURCE_NAME;

public enum DataSourceType {

SOURCE(SOURCE_NAME),
REPLICA(REPLICA_NAME);

private final String name;

DataSourceType(final String name) {
this.name = name;
}

public static class Name {

public static final String ROUTING_NAME = "ROUTING";
public static final String SOURCE_NAME = "SOURCE";
public static final String REPLICA_NAME = "REPLICA";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package touch.baton.infra.database.datasource;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.Map;

public class RoutingDataSource extends AbstractRoutingDataSource {

public static RoutingDataSource createDefaultSetting(final Map<Object, Object> dataSources) {
final RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
routingDataSource.setTargetDataSources(dataSources);
return routingDataSource;
}

@Override
protected Object determineCurrentLookupKey() {
final boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();

if (readOnly) {
return DataSourceType.REPLICA;
}

return DataSourceType.SOURCE;
}
}

0 comments on commit 3f9b9a5

Please sign in to comment.