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
相关文章推荐
- Springboot+Mybatis+Druid 实现多数据源,与事务管理
- Spring中实现多数据源事务管理
- Spring Boot多数据源及其事务管理配置方法
- spring boot + mybatis实现动态切换数据源实例代码
- SpringBoot AOP方式实现多数据源切换的方法
- Spring中实现多数据源事务管理
- Spring中实现多数据源事务管理
- Spring中实现多数据源事务管理
- SpringBoot多数据源事务管理机制
- springboot+mybatis解决多数据源切换事务控制不生效的问题
- springboot之mybatis使用分包实现多数据源
- springboot多数据源指定不同事务管理器
- (十一)Spring Boot整合Mybatis使用druid实现多数据源自动切换
- springboot+mybatis实现动态切换数据源
- Spring Boot2.0之多数据源事务管理
- 基于纯Java代码的Spring容器和Web容器零配置的思考和实现(1) - 数据源与事务管理
- Spring Boot多数据源及其事务管理配置
- spring-boot+aop实现多数据源切换
- spring boot多数据源 分布式事务管理
- Springboot+atomikos+jta实现分布式事务统一管理