spring + mybatis + 多数据源整合事务
2019独角兽企业重金招聘Python工程师标准>>>
1、核心思想,spring提供了一个DataSource的子类,该类支持多个数据源
org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
该类的源码如下:
org.springframework.jdbc.datasource.lookup;java.sql.Connection;
java.sql.SQLException;
java.util.HashMap;
java.util.Iterator;
java.util.Map;
java.util.Map.Entry;
javax.sql.DataSource;
org.springframework.beans.factory.InitializingBean;
org.springframework.jdbc.datasource.AbstractDataSource;
org.springframework.jdbc.datasource.lookup.DataSourceLookup;
org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
org.springframework.util.Assert;AbstractRoutingDataSource AbstractDataSource InitializingBean {// 注意这里,这里使用Map存放多个数据源Map<Object, Object> targetDataSources;... // 篇幅有限,省略其他代码,有兴趣的同学可以自行研究,还是支持蛮多功能的,比如JNDI等数据源方式 // 注意这个暴露的方法,spring在从数据源中获取数据库连接时,通过这个方法确定数据源DataSource determineTargetDataSource() {Assert.notNull(.resolvedDataSources, );Object lookupKey = .determineCurrentLookupKey();DataSource dataSource = (DataSource).resolvedDataSources.get(lookupKey);(dataSource == && (.lenientFallback || lookupKey == )) {dataSource = .resolvedDefaultDataSource;}(dataSource == ) {IllegalStateException(+ lookupKey + );} {dataSource;}}// 对外暴露的决定数据源的方法,通过外部设置数据源的key值,// spring自行从已存储的数据源中查找指定数据源Object determineCurrentLookupKey();
}
通过分析源码,可以知道我们只需要实现如何动态设置切换数据源的方式即可,可以考虑使用注解的方式在指定的位置添加数据源注解,利用AOP动态指定数据源。
自定义的数据源如下:
com.yao.yz.yaowangdrug.dataSource;org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;DynamicDataSource AbstractRoutingDataSource{Object determineCurrentLookupKey() {DataSourceHolder.();}
}
2、自定义注解,本章节不做过多解释,对于注解有兴趣的同学请自行研究,废话一句:程序员以实际应用为主,研究行的内容请自行学习
com.yao.yz.yaowangdrug.dataSource;java.lang.annotation.*;(RetentionPolicy.)
(ElementType.)
@{String value();
}
3、定义一个数据源切换功能组件,其中数据源存放的方式采用ThreadLocal的形式,我是单独把存放做成一个额外的组件,这个是可以自行决定的,代码如下:
com.yao.yz.yaowangdrug.dataSource;DataSourceHolder {ThreadLocal<String> = InheritableThreadLocal<String>();setDataSourceKey(String dataSource) {.set(dataSource);}Object getDataSourceKey() {.get();}}
com.yao.yz.yaowangdrug.dataSource;org.apache.log4j.Logger;
org.aspectj.lang.JoinPoint;
org.aspectj.lang.reflect.MethodSignature;java.lang.reflect.Method;DynamicAspect {Logger = Logger.(DynamicAspect.);switchDataSource(JoinPoint point) NoSuchMethodException{Object target = point.getTarget();String method = point.getSignature().getName();Class<?>[] classz = target.getClass().getInterfaces();Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getMethod().getParameterTypes();Method m = classz[].getMethod(method, parameterTypes);(m != && m.isAnnotationPresent(.)) {data = m.getAnnotation(.);DataSourceHolder.(data.value());}.info(+ DataSourceHolder.());}}
4、在spring配置文件添加多个数据源,并将多个数据源统一纳入自定义数据源的管理,具体的配置信息如下:
<!--装载配置文件,将数据源的配置做成配置文件,方便管理,有兴趣的同学自行参考--><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location" value="Config.properties"/></bean>
<!--数据源1--><bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="${dataSource1.jdbc.url}" /><property name="user" value="${dataSource1.jdbc.username}" /><property name="password" value="${dataSource1.jdbc.password}" /><property name="minPoolSize" value="${dataSource1.jdbc.minPoolSize}" /><property name="maxPoolSize" value="${dataSource1.jdbc.maxPoolSize}" /></bean>
<!--数据源2--><bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="${dataSource2.jdbc.url}" /><property name="user" value="${dataSource2.jdbc.username}" /><property name="password" value="${dataSource2.jdbc.password}" /><property name="minPoolSize" value="${dataSource2.jdbc.minPoolSize}" /><property name="maxPoolSize" value="${dataSource2.jdbc.maxPoolSize}" /></bean>
<!--自定义数据源,将所有的数据源纳入自定义数据源管理--><bean id="dataSource" class="com.yao.yz.yaowangdrug.dataSource.DynamicDataSource"><property name="targetDataSources"><map> <!-- 对应spring提供的AbstractRoutingDataSource的Map --><entry key="dataSource1" value-ref="dataSource1"/><entry key="dataSource2" value-ref="dataSource2"/></map></property><property name="defaultTargetDataSource" ref="dataSource1"/></bean>
5、配置数据源切换的AOP,代码如下:
<!--动态决定数据源--><bean id="dataSourceSwitchAspect" class="com.yao.yz.yaowangdrug.dataSource.DynamicAspect"/><aop:config><aop:aspect id="dynamicAspect" ref="dataSourceSwitchAspect"><!--数据源切换可以控制为Dao或者service层,请根据实际业务需要自行决定--> <aop:pointcut id="dynamicPointCut" expression="execution(* com.xx.xx.xx.dao.*.*(..))"/><aop:before method="switchDataSource" pointcut-ref="dynamicPointCut"/></aop:aspect></aop:config>
6、使用spring整合mybatis,和一般的整合却别在于使用的数据源为自定义数据源,代码如下:
classpath:ModelMapper.xmlclasspath:ModelMapper1.xmlclasspath:ModelMapper2.xml
注意:目前精力有限,此处为什么可以使用自定义多个数据源的底层原理还没来得及看,有兴趣的同学请自行研究,如果好心的话可以简单的告知我,谢谢你了~~~
7、将自定义数据源纳入spring的事务管理器管理,配置代码如下:
<!--事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!--申明事务回滚的方法和异常信息--><tx:advice id="txAdvic" transaction-manager="transactionManager"><tx:attributes><tx:method name="do*" read-only="false" propagation="REQUIRED" rollback-for="java.lang.Exception"/></tx:attributes></tx:advice><!--申明事务范围--><aop:config><aop:pointcut id="txPointCut" expression="execution(* com.xx.xx.xx.service.*.*(..))"/><aop:advisor advice-ref="txAdvic" pointcut-ref="txPointCut"/></aop:config>
Model类:
com.yao.yz.yaowangdrug.model;DBModel {String ;String ;String getValue() {;}setValue(String value) {.= value;}String getKey() {;}setKey(String key) {.= key;}
}
Dao接口:
com.yao.yz.yaowangdrug.dao;;
com.yao.yz.yaowangdrug.model.DBModel;DBDao {()insert(DBModel dbModel) Exception;}
Service接口:
com.yao.yz.yaowangdrug.service;com.yao.yz.yaowangdrug.model.DBModel;
;DBService {doInsert() Exception;doUpdate() Exception;testSeperateDB() Exception;}
关于事务的控制,有一下几点说明:
1、采用申明或者注解实现事务控制时时,因为开启了事务控制,所以如果是两个不同的数据源Dao,根据spring的事务传播特性,第二个事务开启将使用已有的事务(即将采用第一个数据源的数据库连接)进行事务操作,所以此时事务控制是失效的(即使切面执行了数据源切换)。结论就是跨数据库的事务是无法通过spring的数据库控制实现的!!!请切记。
2、同一个数据源的事务控制和普通的数据源控制是一致的,没有什么区别。
以上代码都是经过测试通过,可以实现跨库的数据方式,主要的应用场景是mysql的数据库读写分离。如果不正确的地方请告知,谢谢!
转载于:https://my.oschina.net/u/1471781/blog/508906
spring + mybatis + 多数据源整合事务相关推荐
- spring+mybatis 多数据源整合
直接看spring的配置吧 <!-- 数据源配置 --> <bean id="ds1" class="org.apache.commons.dbcp ...
- spring+mybatis 多数据源切换
spring+mybatis 多数据源切换 摘自: http://www.oschina.net/code/snippet_347813_12525 1. 代码: DbContextHolder pu ...
- spring mybatis 多数据源配置 jeesite 多数据源配置
spring mybatis 多数据源配置 jeesite 多数据源配置 一.情景描述 在系统数据达到一定的访问量时,遇到单个数据库瓶颈,所以需要扩展数据库,启用第二个数据源资源,项目架构变成 一个服 ...
- Spring+SpringMVC+Mybatis 多数据源整合
原文地址:http://blog.csdn.net/q908555281/article/details/50316137 ----------------------------------- 此篇 ...
- Spring+Mybatis多数据源配置(一)——MySQL与Oracle通过配置切换
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
- springmvc整合mysql_SpringMVC+Spring+Mybatis+Maven+mysql整合
一.准备工作 1.工具:jdk1.7.0_80(64)+tomcat7.0.68+myeclipse10.6+mysql-5.5.48-win32 2. 开发环境安装配置.Maven项目创建(参考:h ...
- spring事务隔离级别、传播行为以及spring+mybatis+atomikos实现分布式事务管理
1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单 ...
- spring+mybatis之声明式事务管理初识(小实例)
前几篇的文章都只是初步学习spring和mybatis框架,所写的实例也都非常简单,所进行的数据访问控制也都很简单,没有加入事务管理.这篇文章将初步接触事务管理. 1.事务管理 理解事务管理之前,先通 ...
- Spring+Mybatis 多数据源配置
2013-03-14 项目目录结构如下: spring配置文件 Xml代码 <?xml version="1.0" encoding="UTF-8"? ...
- Spring+Mybatis多数据源配置(四)——AbstractRoutingDataSource实现数据源动态切换
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
最新文章
- ​【安全牛学习笔记】WPS及其他工具WPS
- Sizeof与Strlen的区别与联系(转)
- 物联网:从源头为生产环境安全把关
- Android Studio的git功能的使用
- 多级菜单栏展开隐藏动画
- pip错误:TypeError: parse() got an unexpected keyword argument 'transport_encoding'
- IntellIJ IDEA 启动 参数 配置
- Java读书笔记(4)-多线程(二)
- MFC SendMessage()函数传递字符串
- 字符串池化,减少了三分之一的内存占用
- (第2篇)一篇文章教你轻松安装hadoop
- 谁顶住双11的世界级流量洪峰?神龙架构负责人等9位大牛现场拆解阿里秘籍
- einops.rearrange、repeat、reduce==>对维度进行操作
- HTTP的请求与响应问题(没有了CSDN,暂时把这里当作论坛了)
- git 安装_Windows系统Git安装教程(详解Git安装过程)
- 团队管理心得--建团队,管事理人
- w ndows7旗舰版网卡驱动,windows7万能网卡驱动官方下载
- 关于“缓存着色(cache coloring, page coloring)”技术的相关资料介绍
- 10分钟入门Pandas(添加一些个人见解)
- 中国区域地面气象要素驱动数据集(1979-2018)数据下载与处理
热门文章
- 四川师范大学计算机科学学院官网,四川师范大学
- 老显卡都涨价了,所以我把坏的显卡拿出来修
- No package ‘glib-2.0‘ found/No package ‘gobject-2.0‘ found
- C语言中用二进制输出一个数字
- MAC编译jogl/gluegen很顺利
- 软件基本功:代码要有道理
- LINUX给机器改名
- 640x360,H264 SPS头如何表示高度?
- 软件一定要联网安装,只有内网就干瞪眼
- 管理感悟:可接受的不参加培训的理由