Skip to content

Commit

Permalink
perf($DataSource): reduce instances of data source
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnymillergh committed Jul 14, 2021
1 parent 7993f40 commit 581ac97
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 76 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package com.jmsoftware.maf.springcloudstarter.database;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.quartz.QuartzDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
Expand All @@ -28,45 +25,32 @@
@ConditionalOnClass({MybatisPlusAutoConfiguration.class})
@AutoConfigureBefore({MybatisPlusAutoConfiguration.class})
public class DataSourceConfiguration {
@Bean("masterDataSource")
@ConfigurationProperties("spring.datasource.dynamic.datasource.master")
public DataSource masterDataSource() {
log.warn("Initial bean: masterDataSource");
return DruidDataSourceBuilder.create().build();
}

@Bean("slave1DataSource")
@ConfigurationProperties("spring.datasource.dynamic.datasource.slave1")
public DataSource slave1DataSource() {
log.warn("Initial bean: slave1DataSource");
return DruidDataSourceBuilder.create().build();
}

@Bean("quartzDataSource")
@QuartzDataSource
@ConfigurationProperties("spring.datasource.dynamic.datasource.quartz")
@Bean("quartzDataSource")
@ConditionalOnProperty(prefix = "spring.quartz", name = "job-store-type", havingValue = "jdbc")
public DataSource quartzDataSource() {
public DataSource quartzDataSource(DynamicRoutingDataSource dynamicRoutingDataSource) {
log.warn("Initial bean: quartzDataSource");
return DruidDataSourceBuilder.create().build();
return dynamicRoutingDataSource.getDataSource(DataSourceEnum.QUARTZ.getDataSourceName());
}

@Bean
@Primary
public DynamicRoutingDataSource dynamicDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
@Qualifier("slave1DataSource") DataSource slave1DataSource) {
log.warn("Loading masterDataSource and slave1DataSource as DynamicDataSource");
public ReadWriteIsolationDynamicRoutingDataSource dynamicDataSource(DynamicRoutingDataSource dynamicRoutingDataSource) {
val targetDataSources = new HashMap<>(4);
targetDataSources.put(DataSourceTypeEnum.MASTER, masterDataSource);
targetDataSources.put(DataSourceTypeEnum.SLAVE1, slave1DataSource);
val dynamicDataSource = new DynamicRoutingDataSource();
dynamicDataSource.setDefaultTargetDataSource(masterDataSource);
targetDataSources.put(DataSourceEnum.MASTER,
dynamicRoutingDataSource.getDataSource(DataSourceEnum.MASTER.getDataSourceName()));
targetDataSources.put(DataSourceEnum.SLAVE1,
dynamicRoutingDataSource.getDataSource(DataSourceEnum.SLAVE1.getDataSourceName()));
val dynamicDataSource = new ReadWriteIsolationDynamicRoutingDataSource();
dynamicDataSource.setDefaultTargetDataSource(dynamicRoutingDataSource.getDataSource("master"));
dynamicDataSource.setTargetDataSources(targetDataSources);
log.warn("Set 'masterDataSource' and 'slave1DataSource' as {}",
ReadWriteIsolationDynamicRoutingDataSource.class.getSimpleName());
return dynamicDataSource;
}

@Bean
public PlatformTransactionManager platformTransactionManager(DynamicRoutingDataSource dynamicRoutingDataSource) {
return new DataSourceTransactionManager(dynamicRoutingDataSource);
public PlatformTransactionManager platformTransactionManager(ReadWriteIsolationDynamicRoutingDataSource readWriteIsolationDynamicRoutingDataSource) {
return new DataSourceTransactionManager(readWriteIsolationDynamicRoutingDataSource);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,44 @@
* @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 6/27/2021 12:07 AM
**/
@Slf4j
public class DataSourceContextHolder {
private static final ThreadLocal<DataSourceTypeEnum> CONTEXT_HOLDER = new ThreadLocal<>();
public final class DataSourceContextHolder {
protected static final ThreadLocal<DataSourceEnum> CONTEXT_HOLDER =
ThreadLocal.withInitial(() -> DataSourceEnum.MASTER);
private static final AtomicInteger COUNTER = new AtomicInteger(-1);
private static final int MAX_COUNT = 9999;

public static DataSourceTypeEnum get() {
return Optional.ofNullable(CONTEXT_HOLDER.get()).orElse(DataSourceTypeEnum.MASTER);
private DataSourceContextHolder() {
}

public static void set(DataSourceTypeEnum dbType) {
public static DataSourceEnum get() {
return Optional.ofNullable(CONTEXT_HOLDER.get()).orElse(DataSourceEnum.MASTER);
}

private static void set(DataSourceEnum dbType) {
CONTEXT_HOLDER.set(dbType);
}

static void master() {
set(DataSourceTypeEnum.MASTER);
public static void master() {
set(DataSourceEnum.MASTER);
if (log.isDebugEnabled()) {
log.debug("Current data source -> {}", DataSourceTypeEnum.MASTER);
log.debug("Current data source -> {}", DataSourceEnum.MASTER);
}
}

static void slave() {
// Simple load-balance for more slave clusters
public static void slave() {
// Simple load-balance for more slave clusters, assumed we got 2 replicas
val index = COUNTER.getAndIncrement() % 2;
if (COUNTER.get() > MAX_COUNT) {
COUNTER.set(-1);
}
// if (index == 0) {
// set(DataSourceTypeEnum.SLAVE1);
// }else {
// set(DataSourceTypeEnum.SLAVE2);
// }
set(DataSourceTypeEnum.SLAVE1);
// if replica data sources are more then 1, the data source needs load balance by index
set(DataSourceEnum.SLAVE1);
if (log.isDebugEnabled()) {
log.debug("Current data source -> {}, index: {}", DataSourceTypeEnum.MASTER, index);
log.debug("Current data source -> {}, index: {}", DataSourceEnum.MASTER, index);
}
}

static void clear() {
public static void clear() {
CONTEXT_HOLDER.remove();
if (log.isDebugEnabled()) {
log.debug("Cleared CONTEXT_HOLDER");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.jmsoftware.maf.springcloudstarter.database;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

/**
* Description: DataSourceEnum, change description here.
*
* @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 6/27/2021 12:03 AM
**/
@Getter
@ToString
@RequiredArgsConstructor
public enum DataSourceEnum {
/**
* Master
*/
MASTER("master"),
/**
* Slave 1
*/
SLAVE1("slave1"),
/**
* Quartz
*/
QUARTZ("quartz"),
;

private final String dataSourceName;
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@
})
})
public class DynamicDataSourceInterceptor implements Interceptor {
/**
* The constant WRITE_OPERATION_SQL_REGEX. Preserved this constant for future use.
*/
@SuppressWarnings("unused")
private static final String WRITE_OPERATION_SQL_REGEX = ".*INSERT.*|.*UPDATE.*|.*DELETE.*";

@Override
public Object intercept(Invocation invocation) throws Throwable {
// Check if the transaction synchronization is active. It it was, would use MASTER data source
Expand Down Expand Up @@ -68,8 +62,12 @@ public Object intercept(Invocation invocation) throws Throwable {
}
log.warn("SQL statement [{}], SqlCommandType: [{}], using 🐬 [{}] data source", mappedStatement.getId(),
mappedStatement.getSqlCommandType().name(), DataSourceContextHolder.get());
val result = invocation.proceed();
DataSourceContextHolder.clear();
Object result;
try {
result = invocation.proceed();
} finally {
DataSourceContextHolder.clear();
}
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
* Description: DynamicDataSource, change description here.
* Description: ReadWriteIsolationDynamicRoutingDataSource, change description here.
*
* @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 6/27/2021 12:06 AM
**/
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
public class ReadWriteIsolationDynamicRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.get();
Expand Down

0 comments on commit 581ac97

Please sign in to comment.