Spring配置双数据源的坑

xiaoxiao2021-03-01  10

一.双数据源:顾名思义,一个项目中使用两套数据源,例如一个是mysql数据库,一个是oracle数据库,又或者同样都是mysql,但是要使用两个库中的数据。

二.最简单的方式是,从service,dao层到spring文件配置完全使用两套,放到不同的包路径下。最后在spring加载的时候,将另一套的配置导入到一套就行,以一个主文件加载就行。

三.遇到的坑

1.对于配置文件中sqlSessionFactory 这个重点保护的bean,需要在配置文件中定义不同的id,否则会出现一个史无前例的超级无敌蛋疼问题:(耗费哥2天的时间才找到这个答案)

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

搜遍了整个度娘,都是说是mapper与接口不对应,或者编译问题,果真蛋疼。

网上常说的问题解决思路:https://blog.csdn.net/true_hsf/article/details/52095199

show代码:

这是第一套数据源相关的配置,spring也是以这个为主文件加载的,在这个里面引入了第二套数据源相关的配置

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd" > <import resource="classpath*:/test1-core-spring/test1-datasource.xml"/> <context:component-scan base-package="com.yunpeng.core.test1"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan> //这里扫码第二套数据源相关的业务类 <context:component-scan base-package="com.yunpeng.core.test2"/> //这里加载第二套数据源相关的数据源配置 <import resource="classpath*:test2-core-spring/test2-core-dao.xml"/> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 使用 annotation 定义事务 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> <!-- MyBatis 配置 --> //重点这里已经有了一个名字叫sqlSessionFactory的bean了,并且只扫描了 //com.yunpeng.core.test1.dao下面的接口,如果当前文件引入的第二套中也有一个叫 //sqlSessionFactory的bean,会把第二套中的覆盖掉,于是只剩下了第一套的 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeAliasesPackage" value="com.yunpeng.core.test1.entity,com.yunpeng.core.test1.enumtype"/> <property name="mapperLocations" value="classpath:/test1-process-mapper/*Mapper.xml"/> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.yunpeng.core.test1.dao"/> <property name="annotationClass" value="org.springframework.stereotype.Repository"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> </beans>

这是第二套数据源的相关配置,重点是sqlSessionFactory这个bean一定不要和第一个的重复。

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd" default-autowire="byName"> <import resource="classpath*:/test2-core-spring/test2-core-datasource.xml"/> <bean id="txManagerTest2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="test2DS" /> <property name="nestedTransactionAllowed" value="true"></property> </bean> <tx:annotation-driven transaction-manager="txManagerTest2" proxy-target-class="true" /> <bean id="transactionTemplateTest2" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="txManagerTest2" /> </bean> <bean id="jdbcTemplateTest2" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="test2DS" /> </bean> //这里的bean一定要与数据源一中的区别开来,否则会被第一套覆盖,这是我加了Test2区分 <bean id="sqlSessionFactoryTest2" class="com.yeepay.g3.utils.persistence.mybatis.SqlSessionFactoryBeanWapper"> <property name="dataSource" ref="test2DS" /> <property name="configLocation" value="classpath:/mybatis/mybatis-config.xml" /> <property name="mapperLocations" value="classpath*:test2-core-mapper/*.xml" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.yunpeng.core.test2.dao" /> <property name="annotationClass" value="org.springframework.stereotype.Repository" /> <property name="sqlSessionFactory" ref="sqlSessionFactoryTest2" /> </bean> </beans>

2.对于配置了双数据源以后,基于注解@Transactional 的事物,死活不起作用,也就是当含有事物的代码抛出了异常后事物不进行回滚。也是找了好久,度娘都说是方法需要是public的,或者同类中不能调用带事物的否则也不起用。然而看了配置,都无卵用。

我的原来的事务配置是:

@Transactional(rollbackFor = Throwable.class)

解决方案是:很意想不到的:

@Transactional(value = "txManagerTest2",rollbackFor = Throwable.class)

只是在这个注解中,添加了一个value,用来区分你是用的双数据源中的那个,问题就解决了。

关于事物注解的介绍:https://www.cnblogs.com/caoyc/p/5632963.html

                                https://www.cnblogs.com/yepei/p/4716112.html

 

转载请注明原文地址: https://www.6miu.com/read-3450056.html

最新回复(0)