springboot 动态数据源问题
1. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
在使用了动态数据源后遇到了该问题,从错误信息来看是因为没有找到
*.xml
文件而导致的,但是在配置文件中
确实添加了相关的配置,这种错误的原因是因为设置数据源后没有设置SqlSessionFactoryBean
的typeAliasesPackage
和mapperLocations
属性或属性无效导致的;
- 解决方法:
如果在应用的入口类中添加了
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
,
在DataSourceConfigure
类的中设置相关属性:
@Bean@ConfigurationProperties(prefix = "mybatis")public SqlSessionFactoryBean sqlSessionFactoryBean() {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dynamicDataSource());return sqlSessionFactoryBean;}
或者直接配置(不推荐该方式):
@Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean() {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setTypeAliasesPackage("typeAliasesPackage");sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("mapperLocations"));sqlSessionFactoryBean.setDataSource(dynamicDataSource());return sqlSessionFactoryBean;}
2. Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
该异常在错误信息中已经说的很清楚了,是因为有多个
DataSource
的实例,所以无法确定该引用那个实例
- 解决方法:
为数据源的某个
Bean
添加@Primary
注解,该Bean
应当是通过DataSourceBuilder.create().build()
得到的Bean
,而不是通过new AbstractRoutingDataSource
的子类实现的Bean
,在本项目中可以是master()
或slave()
得到的DataSource
,不能是dynamicDataSource()
得到的DataSource
3. 通过注解方式动态切换数据源无效
- 请确认注解没有放到 DAO 层方法上, 因为会在 Service 层开启事务,所以当注解在 DAO 层时不会生效
- 请确认以下
Bean
正确配置:
@Bean("dynamicDataSource")public DataSource dynamicDataSource() {DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();Map<Object, Object> dataSourceMap = new HashMap<>(2);dataSourceMap.put("master", master());dataSourceMap.put("slave", slave());// Set master datasource as defaultdynamicRoutingDataSource.setDefaultTargetDataSource(master());// Set master and slave datasource as target datasourcedynamicRoutingDataSource.setTargetDataSources(dataSourceMap);// To put datasource keys into DataSourceContextHolder to judge if the datasource is existDynamicDataSourceContextHolder.dataSourceKeys.addAll(dataSourceMap.keySet());} return dynamicRoutingDataSource;} @Bean@ConfigurationProperties(prefix = "mybatis")public SqlSessionFactoryBean sqlSessionFactoryBean() {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();// Here is very important, if don't config this, will can't switch datasource// put all datasource into SqlSessionFactoryBean, then will autoconfig SqlSessionFactorysqlSessionFactoryBean.setDataSource(dynamicDataSource());return sqlSessionFactoryBean;}
4. @Transactional
注解无效,发生异常不回滚
- 请确认该
Bean
得到正确配置,并且@Transactional
的rollbackFor
配置正确
@Beanpublic PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(dynamicDataSource());}
5. 通过 AOP 判断 DAO 层方法名时切换数据源无效
当切面指向了 DAO 层后无论如何设置切面的顺序,都无法在执行查询之前切换数据源,但是切面改为 Service 层后可以正常工作
解决方法: 请确认
@Transactional
注解是加在方法上而不是 Service 类上,添加了@Transactional
的方法因为在 Service 层开启了事务,
会在事务结束之后才会切换数据源检出
DataSourceTransactionManager
Bean 注入正确
@Bean public PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(dynamicDataSource());}
6. The dependencies of some of the beans in the application context form a cycle
- 错误信息:
The dependencies of some of the beans in the application context form a cycle:produceController (field private cn.com.hellowood.dynamicdatasource.service.ProductService cn.com.hellowood.dynamicdatasource.controller.ProduceController.productService)↓productService (field private cn.com.hellowood.dynamicdatasource.mapper.ProductDao cn.com.hellowood.dynamicdatasource.service.ProductService.productDao)↓productDao defined in file [/Users/hehuimin/Downloads/Dev/SpringBoot/DynamicDataSource/out/production/classes/cn/com/hellowood/dynamicdatasource/mapper/ProductDao.class]↓sqlSessionFactoryBean defined in class path resource [cn/com/hellowood/dynamicdatasource/configuration/DataSourceConfigurer.class]┌─────┐| dynamicDataSource defined in class path resource [cn/com/hellowood/dynamicdatasource/configuration/DataSourceConfigurer.class]↑ ↓| master defined in class path resource [cn/com/hellowood/dynamicdatasource/configuration/DataSourceConfigurer.class]↑ ↓| dataSourceInitializer└─────┘
这是因为在注入
DataSource
的实例的时候产生了循环调用,第一个注入的 Bean 依赖于其他的 Bean, 而被依赖的 Bean 产生依赖传递,依赖第一个
注入的 Bean, 陷入了循环,无法启动项目
- 解决方法:将
@Primary
注解指向没有依赖的 Bean,如:
/*** master DataSource* @Primary 注解用于标识默认使用的 DataSource Bean,因为有三个 DataSource Bean,该注解可用于 master* 或 slave DataSource Bean, 但不能用于 dynamicDataSource Bean, 否则会产生循环调用 * * @ConfigurationProperties 注解用于从 application.properties 文件中读取配置,为 Bean 设置属性* @return data source*/@Bean("master")@Primary@ConfigurationProperties(prefix = "application.server.db.master")public DataSource master() {return DataSourceBuilder.create().build();}@Bean("slave")@ConfigurationProperties(prefix = "application.server.db.slave")public DataSource slave() {return DataSourceBuilder.create().build();}@Bean("dynamicDataSource")public DataSource dynamicDataSource() {DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();Map<Object, Object> dataSourceMap = new HashMap<>(2);dataSourceMap.put("master", master());dataSourceMap.put("slave", slave());// Set master datasource as defaultdynamicRoutingDataSource.setDefaultTargetDataSource(master());// Set master and slave datasource as target datasourcedynamicRoutingDataSource.setTargetDataSources(dataSourceMap);// To put datasource keys into DataSourceContextHolder to judge if the datasource is existDynamicDataSourceContextHolder.dataSourceKeys.addAll(dataSourceMap.keySet());return dynamicRoutingDataSource;}
springboot 动态数据源问题相关推荐
- springboot动态数据源切换(多数据源配置)
动态数据源切换即多数据源切换,由于业务的需要或者历史的遗留等原因,一个项目中配置了多个数据库,用于查询不同类型的数据,因此我们就需要经常在各个库中切换数据源,接下来我们将进行具体的说明: 项目结构如下 ...
- springboot多数据源动态数据源(主从)
多数据源 使用Spring Boot时,默认情况下,配置DataSource非常容易.Spring Boot会自动为我们配置好一个DataSource. 如果在application.yml中指定了s ...
- SpringBoot(十一)-- 动态数据源
SpringBoot中使用动态数据源可以实现分布式中的分库技术,比如查询用户 就在用户库中查询,查询订单 就在订单库中查询. 一.配置文件application.properties # 默认数据源 ...
- 32位数据源中没有mysql_基于 SpringBoot 多数据源 动态数据源 主从分离 快速启动器...
简介 dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器. 其支持 Jdk 1.7+, SpringBoot 1.4 ...
- SpringBoot之——动态数据源(多数据源自动切换)
本文实现案例场景: 某系统除了需要从自己的主要数据库上读取和管理数据外,还有一部分业务涉及到其他多个数据库,要求可以在任何方法上可以灵活指定具体要操作的数据库. 为了在开发中以最简单的方法使用,本文基 ...
- springboot动态多数据源配置和使用(二)
很久之前写一篇静态的springboot多数据源配置,一直没写下篇,这里补充一下自己用动态多数据源的场景和开发逻辑. 之前说的静态多数据源是每个数据源配置一套mapper,现在说说如何动态多数据源共用 ...
- springboot动态多数据源配置和使用(从数据库读取数据源配置)(三)
上两遍已经描述了动态多数据源的原理和基础实现了,前面的数据源配置都是从application.yml中配置多数据源的,这里再拓展补充一下其他场景,如何读取数据源不从application.yml中配置 ...
- SpringBoot多数据源切换,AOP实现动态数据源切换
SpringBoot多数据源切换,AOP实现动态数据源切换 操作数据一般都是在DAO层进行处理,可以选择直接使用JDBC进行编程 或者是使用多个DataSource 然后创建多个SessionFact ...
- SpringBoot实现多数据源,动态数据源自由切换
业务场景 在开发中,可能涉及到在用户的业务中要去查询对应订单的数据,而用户和订单又是分处于不同的数据库的,这样的业务该怎么处理呢? 这种就是多数据源的场景,随着业务量的增大,其实这种情况还是经常能遇到 ...
最新文章
- linux 增量备份镜像,【备份与恢复】合并增量备份与映像副本
- frame,iframe,frameset用法和区别
- 用java编写简单Webserver,理解webserver的功能。
- 用c语言做教学课程安排,C语言入门课程安排
- 文献记录(part52)--基于度相关性的病毒传播模型及其分析
- 在C#中使用代理的方式触发事件 的简单习作
- Redhat7.3安装配置Telnet详细教程
- 机器学习之LDA主题模型算法
- java 全双工服务器_利用Java实现串口全双工通讯_JAVA实例教程_IT部落
- C/C++:各类型变量占用字节
- 基于vue.js的dialog插件art-dialog-vue2.0发布
- 【现代软件工程】6月中旬团队项目心得
- windows配置Hadoop开发环境
- 幼儿识字软件测试自学,2016幼儿识字APP哪家强?最新测评出炉!
- 1、黑塞矩阵Hessian matrix
- 虚拟主机和云服务器有什么区别,我们应该如何选择?
- Simulink Solver
- 告别刷量!公众号的正常阅读曲线是什么样的 ​
- python爬虫之静态网页——全国空气质量指数(AQI)爬取
- javascript通过组合实现继承