spring动态切换数据库支持事务
来源:互联网 发布:知乎周刊哪里下 编辑:程序博客网 时间:2024/05/22 17:17
在项目中有mysql的多个库,在代码中同一个方法可能会操作不同的表。在网上学习了各种方法。大概总结了一下。
1.mycat、cobar等分布式数据库中间件。
可以很好的支持,但是太重量级了,对我们项目有点大材小用。
2.spring的AbstractRoutingDataSource实现数据库连接切换。
可以动态的切换数据源,但是对事务有影响,可以用JTA实现事务一致,但是效率较低。而且我们项目事务可以单库一致就满足需求。所以采用了这种方式。
下面是具体的实现过程:
1)spring的配置文件中配置多个数据源。
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><property name="driverClassName" value="com.mysql.jdbc.Driver" /><property name="url" value="${mysql.url}" /><property name="username" value="${mysql.username}" /><property name="password" value="${mysql.password}" /><!-- 连接池启动时的初始值 --><property name="initialSize" value="1" /><!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 --><property name="maxIdle" value="2" /><!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请一些连接,以避免洪峰来时再申请而造成的性能开销 --><property name="minIdle" value="1" /></bean><bean id="xiaomi" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><property name="driverClassName" value="com.mysql.jdbc.Driver" /><property name="url" value="${mysql.url.xiaomi}" /><property name="username" value="${mysql.username}" /><property name="password" value="${mysql.password}" /><!-- 连接池启动时的初始值 --><property name="initialSize" value="1" /><!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 --><property name="maxIdle" value="2" /><!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请一些连接,以避免洪峰来时再申请而造成的性能开销 --><property name="minIdle" value="1" /></bean>
2)定义动态的数据源
<bean class="com.futuren.wzk.common.datasource.DynamicDataSource"id="dynamicDataSource"><property name="targetDataSources"><map key-type="java.lang.String"><entry value-ref="dataSource" key="wzk"></entry><entry value-ref="xiaomi" key="xiaomi"></entry></map></property><property name="defaultTargetDataSource" ref="dataSource" /></bean>
3)定义动态数据源和辅助类
public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {String type = DataSourceContextHolder.getDataSourceType();return type;}}public class DataSourceContextHolder {private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();/*** @Description: 设置数据源类型* @param dataSourceType* 数据库类型* @return void* @throws*/public static void setDataSourceType(String dataSourceType) {contextHolder.set(dataSourceType);}/*** @Description: 获取数据源类型* @param* @return String* @throws*/public static String getDataSourceType() {return contextHolder.get();}/*** @Description: 清除数据源类型* @param* @return void* @throws*/public static void clearDataSourceType() {contextHolder.remove();}}
4)修改事务管理器的数据源为动态数据源,指定事务注解的排序为2,我们会指定切换数据源的注解为1,这样在事务之前切换数据源,否则在事务之后切换的的话,无效。
<!-- 注解事务处理 --><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dynamicDataSource" /><!-- 启用注解 --><tx:annotation-driven transaction-manager="transactionManager" order="2"/>
5)定义切换数据库的注解和aop切面,指定排序为1,这里有个疑问,通过切点获取代理方法的注解数据,我用的是反射,但是网上有说可以直接作为参数传入的,我一直没有试验成功,不知道哪里有错,后续哪位大神指导的,可以分享一下。
@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface DataSource {String name();}@Component@Aspect@Order(1)public class DataSourceProxy {@Before(value="@annotation(com.futuren.wzk.common.datasource.DataSource)")public void before(JoinPoint jp) {String methodName = jp.getSignature().getName();Method[] methods = jp.getTarget().getClass().getMethods();for(Method method : methods) {if(method.getName().equals(methodName)) {DataSource ds = method.getAnnotation(DataSource.class);DataSourceContextHolder.setDataSourceType(ds.name());}}}}
6)在项目中使用
@Override@Transactional@DataSource(name="ucenter")public int addUser(User user) {userMapper.insert(user);return user.getUid();}
这种方法,只支持单库事务,如果要多库事务,可能要引入JTA,或者是其他自定义实现。或者其他我不知道的技术。欢迎讨论!
0 0
- spring动态切换数据库支持事务
- spring动态切换数据库支持事务
- spring 多数据库支持,动态切换数据库
- Spring动态切换数据库
- 事务:spring事务支持
- 事务:spring事务支持
- spring+hibernate多数据源+动态切换 事务 lazyload一应俱全
- Spring分布式事务在service中动态切换数据源
- Spring分布式事务在service中动态切换数据源
- spring多数据源动态切换及事务
- Spring分布式事务在service中动态切换数据源
- Spring整合Hibernate动态切换SessionFactory (切换数据库方言)
- Spring 事务支持
- Spring 注解事务支持
- Spring 事务支持
- spring+hibernate+mysql实现主从数据库动态切换
- mysql数据库 引擎切换, 事务支持,存储过程非线程安全,需加锁
- 数据库事务 和spring事务
- 【设计模式】单例模式
- 2016年数据科学家将扮演什么角色?
- 机密文件曝光大量美国神秘监控设备(挂灯、垃圾桶、鸟巢)
- java对比两个txt内容,如果有不同就提示。
- 程序猿应该知道的计算机网络知识
- spring动态切换数据库支持事务
- cuda float转换为half计算
- android 进入sd卡 选择apk 并返回路径
- VBA 学习笔记之– Excel 对象篇(一)
- 2016年8月
- iOS开发:地图关键词搜索 MKLocalSearch使用
- 大数据系列文章链接
- 生产者消费者模型
- Android开发者应该深入学习的10个开源应用项目