Spring+MyBatis的双数据源双事务配置以及使用

需求场景:

由于系统需要和第三方系统进行对接,出于开发成本的考虑,双方协议系统间的交互不通过接口,而是互相操作数据库。这时就涉及到了双数据源以及双事务。这方面的资料百度出来的资料比较少,都是只有双数据源的资料,双事务的较少。经过研究测试成功,我总结了如下内容。

1. Sprinng +MyBatis配置

数据源配置

<bean id="dataSource_mysql" class="org.apache.commons.dbcp2.BasicDataSource"  
        destroy-method="close">  
        <property name="driverClassName" value="${jdbc.driver}" />  
        <property name="url" value="${jdbc.url}" />  
        <property name="username" value="${jdbc.username}" />  
        <property name="password" value="${jdbc.password}" />  
        <property name="initialSize" value="${jdbc.initialSize}"></property>  
        <property name="maxTotal" value="${jdbc.maxActive}"></property>  
        <property name="maxIdle" value="${jdbc.maxIdle}"></property>  
        <property name="minIdle" value="${jdbc.minIdle}"></property>  
        <property name="maxWaitMillis" value="${jdbc.maxWait}"></property>  
        <property name="validationQuery" value="${jdbc.validationQuery}"></property>
    </bean> 
    <bean id="dataSource_sqlserver" class="org.apache.commons.dbcp2.BasicDataSource"  
        destroy-method="close">  
        <property name="driverClassName" value="${sqlserver.driver}" />  
        <property name="url" value="${sqlserver.url}" />  
        <property name="username" value="${sqlserver.username}" />  
        <property name="password" value="${sqlserver.password}" />  
        <!-- 初始化连接大小 -->  
        <property name="initialSize" value="${sqlserver.initialSize}"></property>  
        <!-- 连接池最大数量 -->  
        <property name="maxTotal" value="${sqlserver.maxActive}"></property>  
        <!-- 连接池最大空闲 -->  
        <property name="maxIdle" value="${sqlserver.maxIdle}"></property>  
        <!-- 连接池最小空闲 -->  
        <property name="minIdle" value="${sqlserver.minIdle}"></property>  
        <!-- 获取连接最大等待时间 -->  
        <property name="maxWaitMillis" value="${sqlserver.maxWait}"></property>  
        <property name="validationQuery" value="${sqlserver.validationQuery}"></property>
    </bean>  

由于是双事务,所以这里要配置两个。第一个sqlSession和事务配置

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
    	<property name="configLocation" value="classpath:SqlMapConfig.xml"></property> 
        <property name="dataSource" ref="dataSource_mysql" />  
        <!-- 自动扫描mapping.xml文件 -->  
        <property name="mapperLocations" value="classpath:com/wmsnet/mapping/*.xml"></property>
    </bean>  

    <!-- DAO接口所在包名,Spring会自动查找其下的类  -->  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="com.wmsnet.mapper" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>  
    </bean>   

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->  
    <bean id="transactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource_mysql" />  
    </bean>  
	<tx:annotation-driven transaction-manager="transactionManager"/>

第二个SqlSession和事务配置

<bean id="sqlServerSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
    	<property name="configLocation" value="classpath:SqlMapConfig.xml"></property> 
        <property name="dataSource" ref="dataSource_sqlserver" />  
        <!-- 自动扫描mapping.xml文件 -->  
        <property name="mapperLocations" value="classpath:com/wmsnet/mappingsqlserver/*.xml"></property>
    </bean>     

<!-- DAO接口所在包名,Spring会自动查找其下的类 -->  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="com.wmsnet.mappersqlserver" />  
        <property name="sqlSessionFactoryBeanName" value="sqlServerSqlSessionFactory"></property>  
    </bean>

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->  
    <bean id="sqlServerTransactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource_sqlserver" />  
    </bean>  
	<tx:annotation-driven transaction-manager="sqlServerTransactionManager"/>

开始比较想不明白的是sqlSessionFactory为什么要设置成两个,现在看来这个机制应该是根据扫描的包的映射方法来确定选用哪个数据源,可以看到sqlSessionFactory扫描的包是不同的路径下的,这里我要说明一下项目里是有两个路径的mapping和mapper,分别针对不同的数据源。使用的数据源而是跟事务的配置数据源无关。这三个配置文件我这里均是写在applicationContext.xml文件里。

2. 使用方法

默认使用数据源事务@Transactional里不需要写东西

使用第二个数据源的事务

只是在括号里把value值设置成第二个事务的id就行了。如果一个方法需要同时使用两个数据源和事务,@Transactional应该是要写两个,这个我没有试。

以上仅为工作中遇到,写下来记录一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值