您的位置:首页 > 编程语言 > Java开发

springboot+分包,实现多数据源切换和事务管理(靠谱版)

2019-03-15 16:49 281 查看

说明:之前写的这篇springboot+aop+自定义注解,实现多数据源切换(通用版)经过测试有些发现事务无法管理,有时候切换数据源容易失败,现在用一种更靠谱的方式来实现多数据源切换。

 

一.引入相应的maven依赖

[code]<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.5</version>
</dependency>

二.配置数据源

 1.这里application.properties配置了三个数据源

[code]spring.datasource.user.url = jdbc:mysql://10.237.150.79:3306/user?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
spring.datasource.user.username = root
spring.datasource.user.password = root
spring.datasource.user.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.user.type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.user.filters = stat
spring.datasource.user.maxActive = 100
spring.datasource.user.initialSize = 10
spring.datasource.user.maxWait = 60000
spring.datasource.user.minIdle = 500

spring.datasource.china.url = jdbc:mysql://10.237.150.79:3306/china?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
spring.datasource.china.username = root
spring.datasource.china.password = root
spring.datasource.china.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.china.type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.china.filters = stat
spring.datasource.china.maxActive = 100
spring.datasource.china.initialSize = 10
spring.datasource.china.maxWait = 60000
spring.datasource.china.minIdle = 500

spring.datasource.world.url = jdbc:mysql://10.237.150.79:3306/world?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
spring.datasource.world.username = root
spring.datasource.world.password = root
spring.datasource.world.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.world.type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.world.filters = stat
spring.datasource.world.maxActive = 100
spring.datasource.world.initialSize = 10
spring.datasource.world.maxWait = 60000
spring.datasource.world.minIdle = 500

2.分包配置数据源

3.注入第一个数据源

[code]/**
* @Author: guandezhi
* @Date: 2019/3/14 21:06
*/
@Configuration
@MapperScan(basePackages = {"com.gdz.dynamic.mapper.china"}, sqlSessionTemplateRef  = "chinaSqlSessionTemplate")
public class ChinaDataSourceConfig {

@Bean(name = "chinaDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.china")
public DataSource chinaDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = "chinaSqlSessionFactory")
@Primary
public SqlSessionFactory chinaSqlSessionFactory(@Qualifier("chinaDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/china/*.xml"));
return bean.getObject();
}

@Bean(name = "chinaTransactionManager")
@Primary
public DataSourceTransactionManager chinaTransactionManager(@Qualifier("chinaDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}

@Bean(name = "chinaSqlSessionTemplate")
@Primary
public SqlSessionTemplate chinaSqlSessionTemplate(@Qualifier("chinaSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}

4.注入第二个数据源

[code]/**
* @Author: guandezhi
* @Date: 2019/3/14 21:06
*/
@Configuration
@MapperScan(basePackages = {"com.gdz.dynamic.mapper.user"}, sqlSessionTemplateRef = "userSqlSessionTemplate")
public class UserDataSourceConfig {

@Bean(name = "userDataSource")
@ConfigurationProperties(prefix = "spring.datasource.user")
public DataSource userDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = "userSqlSessionFactory")
public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/user/*.xml"));
return bean.getObject();
}

@Bean(name = "userTransactionManager")
public DataSourceTransactionManager userTransactionManager(@Qualifier("userDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}

@Bean(name = "userSqlSessionTemplate")
public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("userSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}

5.注入第三个数据源

[code]/**
* @Author: guandezhi
* @Date: 2019/3/14 21:06
*/
@Configuration
@MapperScan(basePackages = {"com.gdz.dynamic.mapper.world"}, sqlSessionTemplateRef  = "worldSqlSessionTemplate")
public class WorldDataSourceConfig {

@Bean(name = "worldDataSource")
@ConfigurationProperties(prefix = "spring.datasource.world")
public DataSource worldDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = "worldSqlSessionFactory")
public SqlSessionFactory worldSqlSessionFactory(@Qualifier("worldDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/world/*.xml"));
return bean.getObject();
}

@Bean(name = "worldTransactionManager")
public DataSourceTransactionManager worldTransactionManager(@Qualifier("worldDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}

@Bean(name = "worldSqlSessionTemplate")
public SqlSessionTemplate worldSqlSessionTemplate(@Qualifier("worldSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}

这样就已经可以实现多数据源的切换了。

总结:

         1.事务的使用必须要指明是哪个数据源的事务管理器,否则事务失效

            例如:@Transactional(value = "userTransactionManager")

         2.如果一个方法涉及多个数据源操作,此时无法做到同时回滚,尽量避免这种操作,

           这里涉及到分布式事务处理,可自行研究。

代码地址:https://github.com/dezhiguan/DynamicDataSource2/tree/master

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: