Closed Shmily-candy closed 2 years ago
package com.yb.cloud.mgr.config;
import com.baomidou.mybatisplus.core.MybatisConfiguration; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; import com.yb.cloud.mgr.enums.DataSourceKey; import com.zaxxer.hikari.HikariDataSource; import io.seata.rm.datasource.DataSourceProxy; import org.apache.ibatis.plugin.Interceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource; import java.io.IOException; import java.util.HashMap; import java.util.Map;
/**
@Configuration public class DataSourcesProxyConfig {
@Autowired
private Environment environment;
@Bean(name = "originMaster")
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.master")
public DataSource dataSourceMaster() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setDriverClassName(environment.getProperty("spring.datasource.dynamic.datasource.master.driver-class-name"));
hikariDataSource.setJdbcUrl(environment.getProperty("spring.datasource.dynamic.datasource.master.url"));
hikariDataSource.setUsername(environment.getProperty("spring.datasource.dynamic.datasource.master.username"));
hikariDataSource.setPassword(environment.getProperty("spring.datasource.dynamic.datasource.master.password"));
hikariDataSource.setReadOnly(Boolean.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.master.hikari.is-read-only")));
hikariDataSource.setConnectionTimeout(Long.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.master.hikari.connection-timeout")));
hikariDataSource.setIdleTimeout(Long.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.master.hikari.idle-timeout")));
hikariDataSource.setMaxLifetime(Long.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.master.hikari.max-lifetime")));
hikariDataSource.setMaximumPoolSize(Integer.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.master.hikari.max-pool-size")));
return hikariDataSource;
}
@Bean(name = "originSlave")
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.slave")
public DataSource dataSourceSlave() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setJdbcUrl(environment.getProperty("spring.datasource.dynamic.datasource.slave.url"));
hikariDataSource.setDriverClassName(environment.getProperty("spring.datasource.dynamic.datasource.slave.driver-class-name"));
hikariDataSource.setUsername(environment.getProperty("spring.datasource.dynamic.datasource.slave.username"));
hikariDataSource.setPassword(environment.getProperty("spring.datasource.dynamic.datasource.slave.password"));
hikariDataSource.setReadOnly(Boolean.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.slave.hikari.is-read-only")));
hikariDataSource.setConnectionTimeout(Long.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.slave.hikari.connection-timeout")));
hikariDataSource.setIdleTimeout(Long.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.slave.hikari.idle-timeout")));
hikariDataSource.setMaxLifetime(Long.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.slave.hikari.max-lifetime")));
hikariDataSource.setMaximumPoolSize(Integer.valueOf(environment.getProperty("spring.datasource.dynamic.datasource.slave.hikari.max-pool-size")));
return hikariDataSource;
}
@Bean(name = "master")
public DataSourceProxy masterDataSourceProxy(@Qualifier("originMaster") DataSource dataSource) {
return new DataSourceProxy(dataSource);
}
@Bean(name = "slave")
public DataSourceProxy slaveDataSourceProxy(@Qualifier("originSlave") DataSource dataSource) {
return new DataSourceProxy(dataSource);
}
@Bean("dynamicDataSource")
public DataSource dynamicDataSource(@Qualifier("master") DataSource dataSourceMaster,
@Qualifier("slave") DataSource dataSourceSlave) {
DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
Map<Object, Object> dataSourceMap = new HashMap<>(2);
dataSourceMap.put(DataSourceKey.MASTER, dataSourceMaster);
dataSourceMap.put(DataSourceKey.SLAVE, dataSourceSlave);
dynamicRoutingDataSource.setDefaultTargetDataSource(dataSourceMaster);
dynamicRoutingDataSource.setTargetDataSources(dataSourceMap);
DynamicDataSourceContextHolder.getDataSourceKeys().addAll(dataSourceMap.keySet());
return dynamicRoutingDataSource;
}
@Bean(name = "transactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier("dynamicDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
@ConfigurationProperties(prefix = "mybatis")
public MybatisSqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("dynamicDataSource") DataSource dataSource, PaginationInterceptor paginationInterceptor) throws IOException {
// 这里用 MybatisSqlSessionFactoryBean 代替了 SqlSessionFactoryBean,否则 MyBatisPlus 不会生效
MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
mybatisSqlSessionFactoryBean.setDataSource(dataSource);
mybatisSqlSessionFactoryBean.setMapperLocations(
new PathMatchingResourcePatternResolver().
getResources(environment.getProperty("mybatis-plus.mapper-locations"))
);
MybatisConfiguration configuration = mybatisSqlSessionFactoryBean.getConfiguration();
if (configuration == null) {
configuration = new MybatisConfiguration();
}
configuration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
//设置分页
Interceptor[] plugins = {paginationInterceptor};
mybatisSqlSessionFactoryBean.setPlugins(plugins);
return mybatisSqlSessionFactoryBean;
}
}
@Override
public void registerResource(Resource resource) {
DataSourceProxy dataSourceProxy = (DataSourceProxy) resource;
dataSourceCache.put(dataSourceProxy.getResourceId(), dataSourceProxy);
super.registerResource(dataSourceProxy);
}
不要代理从库
读写都有的场景都走主库,纯写也走主库
自动代理也记得关掉
spring的数据源自动配置已经排除了,那纯读的时候 怎么整?
mp-starter 也排除了 现在是 动态路由 通过指定master还是slave来决定 读写还是读
嗯嗯 解决了 谢谢 只把 代理关掉 动态路由主从那块 从库不走代理即可。谢谢 da lao
Ⅰ. Issue Description
我hikari cp手动代理数据源配置了主从,注册源的时候:从库的配置覆盖了主库,导致回滚的时候 产生只读的问题,请问如何解决?
Ⅱ. Describe what happened
If there is an exception, please attach the exception trace:
Ⅲ. Describe what you expected to happen
Ⅳ. How to reproduce it (as minimally and precisely as possible)
Ⅴ. Anything else we need to know?
Ⅵ. Environment: