Spring配置双数据源的坑

一.双数据源:顾名思义,一个项目中使用两套数据源,例如一个是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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值