spring无事务的数据源切换,和带事务的数据源切换
2016-04-07 11:40
495 查看
最近在配置spring框架时需要使用多数据源,其中遇到一些问题,特此记录
无事务数据源切换
见 http://blog.csdn.net/shadowsick/article/details/8878448
主要说一下带事务数据源切换的配置
首先在spring-database.xml中配置两个数据源(默认数据源),和应用的切面
多数据源route类
数据源内容配置类
上边xml中配置的 dataSourceInterceptor 会找到class DataSourceInterceptor,并执行set**方法和clear**方法,并设置CustomerType(数据源)给contextHolder,以便于
在determineCurrentLookupKey方法中可以获得到改变后的数据源.
然后是事务的配置
在spring-application.xml中
加上如下配置
在web.xml中加上了spring管理hibernate的session
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意:加上事务时候,我这的切面切的是service层,当切换数据源时,一定要把所有的方法加到你要实施事务的attributes中,或者写成*(任何方法都实施事务)也可以.否则不能切换数据源,详情可见http://blog.csdn.net/wangpeng047/article/details/43450189的博客
这里一句话带过,事务和数据源是绑定的,当你在service层加上事务,你想在dao层切换数据源是不可以的,由于在进入该层之前事务已经通过拦截器开启,因此在该层切换数据源也是不行的.
以上是我本地配置的带事务管理的数据源切换实例,如有问题感谢大家提出指正互相学习.
无事务数据源切换
见 http://blog.csdn.net/shadowsick/article/details/8878448
主要说一下带事务数据源切换的配置
首先在spring-database.xml中配置两个数据源(默认数据源),和应用的切面
<!-- backend数据源 --> <bean id="dataSourceBackend" class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="${backend.url}"></property> <property name="username" value="${backend.username}"></property> <property name="password" value="${backend.password}"></property> </bean> <!-- pi数据源 --> <bean id="dataSourcePIDB" class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="${pi.url}"></property> <property name="username" value="${pi.username}"></property> <property name="password" value="${pi.password}"></property> </bean> <!-- 多数据源配置 --> <bean id="dynamicDataSource" class="com.test.base.dao.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry value-ref="dataSourceBackend" key="dataSourceBackend"></entry> <entry value-ref="dataSourcePIDB" key="dataSourcePIDB"></entry> </map> </property> <!--默认数据源--> <property name="defaultTargetDataSource" ref="dataSourceBackend"> </property> </bean> <aop:config><!--切面--> <aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor"> <aop:pointcut id="daoBackend" expression="execution(* com.test.backend.service.ReportService.*(..))" /> <aop:before pointcut-ref="daoBackend" method="setdataSourceBackend" /> <aop:pointcut id="daopidb" expression="execution(* com.test.backend.service.MacIpService.*(..))" /> <aop:before pointcut-ref="daopidb" method="setdataSourcePIDB" /><!--切面before调用的方法--> <aop:after pointcut-ref="daopidb" method="cleardataSource" /><!--切面after调用的方法--> </aop:aspect> </aop:config>
多数据源route类
public class DynamicDataSource extends AbstractRoutingDataSource{ @Override protected Object determineCurrentLookupKey() { return DatabaseContextHolder.getCustomerType(); } }
数据源内容配置类
public class DatabaseContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { return contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } }
@Component public class DataSourceInterceptor { public void setdataSourceBackend(JoinPoint jp) { DatabaseContextHolder.setCustomerType("dataSourceBackend"); } public void setdataSourcePIDB(JoinPoint jp) { DatabaseContextHolder.setCustomerType("dataSourcePIDB"); } public void cleardataSource(JoinPoint jp){ DatabaseContextHolder.clearCustomerType(); } }
上边xml中配置的 dataSourceInterceptor 会找到class DataSourceInterceptor,并执行set**方法和clear**方法,并设置CustomerType(数据源)给contextHolder,以便于
在determineCurrentLookupKey方法中可以获得到改变后的数据源.
然后是事务的配置
在spring-application.xml中
加上如下配置
</pre></p><p><pre name="code" class="html"> <import resource="spring-database.xml"/> <!-- 配置SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dynamicDataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.autoReconnect">true</prop> <prop key="hibernate.connection.autocommit">true</prop> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <property name="packagesToScan" value="com.test.backend.entity" /> </bean> <!-- 配置一个事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 事务管理 start--> <tx:annotation-driven transaction-manager="transactionManager" /> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="del*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="find*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice> <aop:config> <!-- 实施事务 --> <aop:pointcut id="txPointcut" expression="execution(* com.test.backend.service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" /> </aop:config> <!-- 事务管理 end-->
在web.xml中加上了spring管理hibernate的session
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意:加上事务时候,我这的切面切的是service层,当切换数据源时,一定要把所有的方法加到你要实施事务的attributes中,或者写成*(任何方法都实施事务)也可以.否则不能切换数据源,详情可见http://blog.csdn.net/wangpeng047/article/details/43450189的博客
这里一句话带过,事务和数据源是绑定的,当你在service层加上事务,你想在dao层切换数据源是不可以的,由于在进入该层之前事务已经通过拦截器开启,因此在该层切换数据源也是不行的.
以上是我本地配置的带事务管理的数据源切换实例,如有问题感谢大家提出指正互相学习.
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring Boot 开发微服务
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- SQL Server误区30日谈 第1天 正在运行的事务在服务器故障转移后继续执行
- 浅析SQL Server中包含事务的存储过程
- Mysql中的事务是什么如何使用
- MySql的事务使用与示例详解
- C#分布式事务的超时处理实例分析
- C#中的事务用法实例分析
- SQL Server的事务操作隔离模式介绍
- MySQL中事务概念的简洁学习教程
- C#处理Access中事务的方法
- oracle 合并查询 事务 sql函数小知识学习
- 模拟Spring的简单实现
- Spring整合WebSocket应用示例(上)
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解