解决spring mvc 多数据源切换,不支持事务控制的问题
程序员文章站
2024-02-27 13:33:15
一个项目中需要使用两个数据库,oracle 和mysql,于是参考各个blog,实现此功能。写好后才发现,原来的事务失效了,我去...
spring-mybatis.xm...
一个项目中需要使用两个数据库,oracle 和mysql,于是参考各个blog,实现此功能。写好后才发现,原来的事务失效了,我去...
spring-mybatis.xml 配置
<bean id="configreader" class="org.springframework.beans.factory.config.preferencesplaceholderconfigurer"> <property name="locations"> <list> <value>classpath:spring/db.properties</value> </list> </property> <property name="ignoreresourcenotfound" value="true"/> </bean> <bean id="datasource" class="com.mchange.v2.c3p0.combopooleddatasource"> <property name="driverclass" value="${jdbc.oracle.driverclassname}"></property> <property name="jdbcurl" value="${jdbc.oracle.url}"></property> <property name="user" value="${jdbc.oracle.username}"></property> <property name="password" value="${jdbc.oracle.userpassword}"></property> <property name="acquireincrement" value="5"></property> <property name="initialpoolsize" value="5"></property> <property name="maxidletime" value="60"></property> <property name="maxpoolsize" value="100"></property> <property name="minpoolsize" value="5"></property> </bean> <!-- 配置数据源:mysql start --> <bean name="mysqldatasource" class="com.alibaba.druid.pool.druiddatasource" init-method="init" destroy-method="close"> <property name="driverclassname" value="${jdbc.mysql.driverclassname}"/> <property name="url" value="${jdbc.mysql.url}"/> <property name="username" value="${jdbc.mysql.username}"/> <property name="password" value="${jdbc.mysql.userpassword}"/> <!-- 初始化连接大小 --> <property name="initialsize" value="5"/> <!-- 连接池最大使用连接数量 --> <property name="maxactive" value="30"/> <!-- 连接池最小空闲 --> <property name="minidle" value="2"/> <!-- 获取连接最大等待时间 --> <property name="maxwait" value="300"/> <property name="validationquery" value="select 1"/> <property name="testonborrow" value="false"/> <property name="testonreturn" value="false"/> <property name="testwhileidle" value="true"/> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timebetweenevictionrunsmillis" value="10000"/> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minevictableidletimemillis" value="30000"/> <!-- 打开removeabandoned功能 --> <property name="removeabandoned" value="true"/> <!-- 1800秒,也就是30分钟 --> <property name="removeabandonedtimeout" value="1800"/> <!-- 关闭abanded连接时输出错误日志 --> <property name="logabandoned" value="true"/> <!-- 监控数据库 --> <property name="filters" value="stat"/> </bean> <bean id="multipledatasource" class="com.we.database.multipledatasource"> <property name="defaulttargetdatasource" ref="datasource"/> <property name="targetdatasources"> <map> <entry key="oracledatasource" value-ref="datasource"/> <entry key="mysqldatasource" value-ref="mysqldatasource"/> </map> </property> </bean> <!-- oracle mybatis file --> <bean id="sqlsessionfactory" class="org.mybatis.spring.sqlsessionfactorybean"> <property name="datasource" ref="multipledatasource"/> <!--<property name="configlocation" value="classpath:configuration.xml" /> --> <property name="mapperlocations" value="classpath:com/we/dao/mapper/*.xml"/> </bean> <bean class="org.mybatis.spring.mapper.mapperscannerconfigurer"> <property name="basepackage" value="com.we.dao"/> <property name="sqlsessionfactorybeanname" value="sqlsessionfactory"/> </bean> <!-- configure transaction --> <bean id="transactionmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager"> <property name="datasource" ref="datasource"/> </bean> <!-- annotation transaction --> <tx:annotation-driven transaction-manager="transactionmanager" proxy-target-class="true"/> <!-- interception transatcion --> <tx:advice id="transactionadvice" transaction-manager="transactionmanager"> <tx:attributes> <tx:method name="add*" propagation="required"/> </tx:attributes> </tx:advice> <!-- 配置数据库注解aop --> <bean id="datasourceaspect" class="com.we.database.datasourceaspect"/> <aop:config> <aop:pointcut id="transactionpointcut" expression="execution(* com.wewe.licai.service..*impl.*(..))"/> <aop:advisor pointcut-ref="transactionpointcut" advice-ref="transactionadvice" order="2"/> <!--数据源选择切面,保证在事务开始之前执行--> <aop:advisor pointcut-ref="transactionpointcut" advice-ref="datasourceaspect" order="1" /> </aop:config>
注解切换,默认使用oracle数据源
@documented @retention(retentionpolicy.runtime) @target({elementtype.method,elementtype.type}) public @interface datasource { string name() default datasource.oracledatasource; string mysqldatasource = "mysqldatasource"; string oracledatasource = "oracledatasource"; }
注解方式实现切换数据源,搜索注释,更换注释上面的数据源,支持类注释和方法注释
/** * created by eastday on 2017/9/21. */ public class datasourceaspect implements methodbeforeadvice,afterreturningadvice { @override public void afterreturning(object returnvalue, method method, object[] args, object target) throws throwable { multipledatasource.cleardatasource(); } @override public void before(method method, object[] args, object target) throws throwable { //首先取类上的数据源 if(method.getdeclaringclass().isannotationpresent(datasource.class) && !method.isannotationpresent(datasource.class)) { datasource datasource = method.getdeclaringclass().getannotation(datasource.class); multipledatasource.setdatasource(datasource.name()); //方法上的数据源 优先级高于类上的 } else if (method.isannotationpresent(datasource.class)) { datasource datasource = method.getannotation(datasource.class); multipledatasource.setdatasource(datasource.name()); } else { multipledatasource.setdatasource(datasource.oracledatasource); } } }
继承abstractroutingdatasource实现数据源切换
public class multipledatasource extends abstractroutingdatasource { private static final threadlocal<string> datasources = new inheritablethreadlocal<string>(); public static void setdatasource(string datasource) { datasources.set(datasource); } //清除数据源 public static void cleardatasource() { datasources.remove(); } @override protected object determinecurrentlookupkey() { return datasources.get(); } }
使用demo
@datasource(name = datasource.mysqldatasource) public class contentserviceimpl implements icontentservice { @autowired private icontentdao contentdao; @override public content queryone(string type) { return contentdao.queryone(type); } }
以上这篇解决spring mvc 多数据源切换,不支持事务控制的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
上一篇: spring与mybatis整合配置文件