spring+mybatis 配置了三个数据源,事物失效

太黑_thj 发布于 2017/04/11 17:01
阅读 250
收藏 2

问题:

spring+mybatis 配置了三个数据源,事物失效,手动使用

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 

也不回滚;

背景:

有个项目使用SSM框架,需要访问多个数据源,我就配置了多个数据源到项目里面

DB源配置文件:如下(配置了三个数据源,三个事务模板)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

	<context:property-placeholder location="classpath:prop/db.properties" ignore-unresolvable="true"/>  
	<!-- 配置连接池 druid  -->
	<!-- 数据库resource -->
	<bean id="dataSourceResource" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="driverClassName" value="${db.mysql.driver}" />
		<property name="url" value="${db.resource.url}" />
		<property name="username" value="${db.resource.user}" />
		<property name="password" value="${db.resource.pwd}" />
		<property name="filters" value="stat,log4j" />
		<property name="maxActive" value="50" />
		<property name="initialSize" value="1" />
		<property name="maxWait" value="60000" />
		<property name="minIdle" value="2" />
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<property name="minEvictableIdleTimeMillis" value="300000" />
		<property name="validationQuery" value="SELECT 'x'" />
		<property name="testWhileIdle" value="true" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
	</bean>
	    <!-- 使用annotation定义事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" /> 
	<!-- 配置事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSourceResource" />
	</bean>
		<!-- 配置事务模板 -->
	<bean id="transactionTemplate"
		class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="transactionManager" />
	</bean>
	
	
	
	
	<!-- 数据库LG_ADCoreDB -->
	<bean id="dataSourceLab" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="driverClassName" value="${db.mysql.driver}" />
		<property name="url" value="${db.lab.url}" />
		<property name="username" value="${db.lab.user}" />
		<property name="password" value="${db.lab.pwd}" />
		<property name="filters" value="stat,log4j" />
		<property name="maxActive" value="50" />
		<property name="initialSize" value="1" />
		<property name="maxWait" value="60000" />
		<property name="minIdle" value="2" />
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<property name="minEvictableIdleTimeMillis" value="300000" />
		<property name="validationQuery" value="SELECT 'x'" />
		<property name="testWhileIdle" value="true" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
	</bean>
	
	<!-- 配置事务管理器 -->
	<bean id="transactionManagerLab"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSourceLab" />
	</bean>
	
	
	
	<!-- 数据库lg_user_data -->
	<bean id="dataSourceLud" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="driverClassName" value="${db.mysql.driver}" />
		<property name="url" value="${db.lud.url}" />
		<property name="username" value="${db.lud.user}" />
		<property name="password" value="${db.lud.pwd}" />
		<property name="filters" value="stat,log4j" />
		<property name="maxActive" value="50" />
		<property name="initialSize" value="1" />
		<property name="maxWait" value="60000" />
		<property name="minIdle" value="2" />
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<property name="minEvictableIdleTimeMillis" value="300000" />
		<property name="validationQuery" value="SELECT 'x'" />
		<property name="testWhileIdle" value="true" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
	</bean>
	
	<!-- 配置事务管理器 -->
	<bean id="transactionManagerLud"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSourceLud" />
	</bean>
	
</beans>

spring-application.xml:如下(这里主要就配了事物的传播性)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

	<util:properties id="lgResSysPro" location="classpath:prop/lgResSys.properties"/>
	<bean id="lgResSys" class="com.lg.res.init.LgResSys"/>
	<!-- 数据源配置 -->
	<import resource="classpath:config/spring-db.xml"/>
	
	<!-- 配置mybatis -->
	<import resource="classpath:config/spring-mybatis.xml"/>
	

	<!-- Spring AOP config 配置事务属性 解释一下(* com.evan.crm.service.*.*(..))中几个通配符的含义: 
		第一个 * —— 通配 任意返回值类型 第二个 * —— 通配 包com.evan.crm.service下的任意class 第三个 * —— 通配 
		包com.evan.crm.service下的任意class的任意方法 第四个 .. —— 通配 方法可以有0个或多个参数 -->
	<aop:config>
		<aop:advisor pointcut="execution(* com.lg.res.service.*.*(..))"
			advice-ref="txAdvice" />
		<aop:advisor pointcut="execution(* com.lg.lud.service.*.*(..))"
			advice-ref="txAdvice" />
		<aop:advisor pointcut="execution(* com.lg.lab.service.*.*(..))"
			advice-ref="txAdvice" />
	</aop:config>
	<!-- 配置事务的传播特性 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true" />
			<tx:method name="query*" read-only="true" />
			<tx:method name="find*" read-only="true" />
			<tx:method name="load*" read-only="true" />
			<tx:method name="select*" read-only="true" />
			<tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />
		</tx:attributes>
	</tx:advice>
</beans>

mybatis的配置文件:如下(主要是配置了每个mapper对应的数据源)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
	
	<!-- resource 开始 -->
	<!-- 配置mybatis数据源与xml的匹配关系 -->
	<bean id="sqlSessionFactoryResource" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSourceResource" />
		<property name="configLocation">
			<value>classpath:config/mybatis.xml</value>
		</property>
		<property name="mapperLocations">
			<array>
				<value>classpath:xml/*.xml</value>
			</array>
		</property>

	</bean>
	<!-- spring与mybatis整合配置,扫描所有mapper -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.lg.res.mapper" />
		<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> 用这个的话会导致spring无法加载配置文件 -->
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryResource" />
	</bean>
	<!-- resource 结束 -->
	
	<!-- resource 开始 -->
	<!-- 配置mybatis数据源与xml的匹配关系 -->
	<bean id="sqlSessionFactoryLab" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSourceLab" />
		<property name="configLocation">
			<value>classpath:config/mybatis.xml</value>
		</property>
		<property name="mapperLocations">
			<array>
				<value>classpath:lab/xml/*.xml</value>
			</array>
		</property>

	</bean>
	<!-- spring与mybatis整合配置,扫描所有mapper -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.lg.lab.mapper" />
		<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> 用这个的话会导致spring无法加载配置文件 -->
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryLab" />
	</bean>
	<!-- resource 结束 -->
	
	<!-- user data 开始 -->
	<!-- 配置mybatis数据源与xml的匹配关系 -->
	<bean id="sqlSessionFactoryLud" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSourceLud" />
		<property name="configLocation">
			<value>classpath:config/mybatis.xml</value>
		</property>
		<property name="mapperLocations">
			<array>
				<value>classpath:lud/xml/*.xml</value>
			</array>
		</property>

	</bean>
	<!-- spring与mybatis整合配置,扫描所有mapper -->
		<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> 用这个的话会导致spring无法加载配置文件 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.lg.lud.mapper" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryLud" />
	</bean>
	<!-- user data 结束-->
</beans>

求个大神给点解决建议;

目前应急方案:放弃事物,修改逻辑,自己用逻辑来充当事物使用(PS:太尼玛痛苦了,而且代码写得好恶心)

加载中
返回顶部
顶部