spring多数据源分布式事务的分析与解决方案
一、概述
1、业务背景
对老系统进行重构合并,导致新系统需要同时对3个数据库进行管理。由于出现跨库业务,需要实现分布式事务。
2、开发环境
spring框架版本 4.3.10.RELEASE
持久层为结合mybatis写的领域模型,如
每一个entity对应数据库的一张表,@DataSource注解(自定义)了对应数据源的key值。所以一个业务中可能存在数据源的切换。
事务采用注解@Transaction驱动。
二、spring对多数据源的支持
spring框架通过抽象类AbstractRoutingDataSource来实现多数据源支持。
AbstractRoutingDataSource中有一个抽象方法determineCurrentLookupKey()。子类实现该方法即可。
举例如下:
package com.cmcc.cq.xx.common.mybatis; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override
protected Object determineCurrentLookupKey() {
return getDataSourceType();
} private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setDataSourceType(String dataSourceType){
contextHolder.set(dataSourceType);
} public static String getDataSourceType(){
return contextHolder.get();
} public static void clearDataSourceType(){
contextHolder.remove();
}
}
ThreadLocal保存当前线程的数据源,执行数据库操作之前会通过解析注解@DataSource设置下次操作的数据源类型,即相应的key值(见后文数据源配置)。
到此,在不使用事务的情况下,可以完成多数据源切换。
三、spring分布式事务支持
1、DataSourceTransactionManager不支持多数据源
DataSourceTransactionManager事务管理器是一个单数据源事务管理器,在实例化时候会注入一个数据源。
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dynamicDataSource">
</property>
</bean>
注意:虽然我们注入的是一个动态数据源,但是DataSourceTransactionManager不会因为我们使用动态数据源而跟着变化。
因为DataSourceTransactionManager开始事务时获取数据库connection时并不是每次都通过dataSource来获取,一般都是通过ConnectionHolder类获得。
所以开启事务会报找不到表或视图的异常。
同时DataSourceTransactionManager也不能实现跨库事务的一致性。
2、JtaTransactionManager支持分布式事务
JtaTransactionManager事务管理器只是提供一个接入方式,并没有做相应的实现,目前比较流行的分布式事务第三方实现是atomikos和jotm。其中jotm更新日期是2010年,建议使用atomikos。
两者配置也是大同小异,以atomikos为例。
引入maven依赖
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jdbc</artifactId>
<version>3.7.0</version>
</dependency>
首先是数据源的配置,必须要使用类com.atomikos.jdbc.AtomikosDataSourceBean,不能再使用其他的连接池替代。xaDataSourceClassName要根据数据库选择相应的类,在数据库对应的驱动包里可以找到。
<bean id="dataSource3" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="close">
<property name="uniqueResourceName" value="key值"/>
<property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource"/>
<property name="xaProperties">
<props>
<prop key="URL">${jdbc.dataSource.url3}</prop>
<prop key="user">${jdbc.dataSource.username3}</prop>
<prop key="password">${jdbc.dataSource.password3}</prop>
</props>
</property>
<property name="minPoolSize" value="${jdbc.dataSource.minimumIdle3}" />
<property name="maxPoolSize" value="${jdbc.dataSource.maximumPoolSize3}" />
<property name="borrowConnectionTimeout" value="${jdbc.dataSource.connectionTimeout3}" />
<property name="testQuery" value="${jdbc.dataSource.connectionTestQuery3}" />
<property name="maintenanceInterval" value="60" />
<property name="maxIdleTime" value="${jdbc.dataSource.idleTimeout3}"></property>
</bean>
然后是JtaTransactionManager事务管理器配置。
JtaTransactionManager有两个重要属性需要配置transactionManager和userTransaction。对应的配置类如下:
注:在jotm中只需配置transactionManager属性
最后是atomikos的配置文件jta.properties。
配置路径:根路径
jta.properties也可命名为transactions.properties,如果不配置也可以启动项目,因为几乎所有配置项都有默认值。
transactions.properties配置
spring多数据源分布式事务的分析与解决方案的更多相关文章
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 VC中进程与进程之间共享内存 .net环境下跨进程、高频率读写数据 使用C#开发Android应用之WebApp 分布式事务之消息补偿解决方案
C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). ...
- Spring Boot2.0之多数据源分布式事务问题
分布式事务解决方案的问题, 分布式事务产生的原因: 多个不同的服务连接不同的数据源 ,做分布式事务的管理. 这种情况是连接两个数据源的情况,然后事务管理器是这样的 只管理了test02的这端业务代码. ...
- spring 多数据源一致性事务方案
spring 多数据源配置 spring 多数据源配置一般有两种方案: 1.在spring项目启动的时候直接配置两个不同的数据源,不同的sessionFactory.在dao 层根据不同业务自行选择使 ...
- SpringBoot 多数据源分布式事务
1.pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- (附源码gitHub下载地址)spring boot -jta-atomikos分布式事务
应用场景:双数据源,就是某些项目会涉及到两个数据源或者两个以上的数据源,这个多数据源的项目一般是数据同步,也就是把数据从另一个系统中,保存到另一个系统,两边的 数据库又不一样,比如一个Mysql.一个 ...
- spring boot:使用分布式事务seata(druid 1.1.23 / seata 1.3.0 / mybatis / spring boot 2.3.2)
一,什么是seata? Seata:Simpe Extensible Autonomous Transcaction Architecture, 是阿里中间件开源的分布式事务解决方案. 前身是阿里的F ...
- Spring Cloud Alibaba分布式事务组件 seata 详解(小白都能看懂)
一,什么是事务(本地事务)? 指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行. 简单的说,事务就是并发控制的单位,是用户定义的一个操作序列. 而一个逻辑工作单元要成 ...
- (WebFlux)003、多数据源R2dbc事务失效分析
一.背景 最近项目持续改造,然后把SpringMVC换成了SpringWebflux,然后把Mybatis换成了R2dbc.中间没有遇到什么问题,一切都那么的美滋滋,直到最近一个新需求的出现,打破了往 ...
- ELK(ElasticSearch, Logstash, Kibana) v5.3.2 分布式日志收集分析最佳解决方案 基于CentOS 7 ( 一 )
[root@localhost temp]# .tar.gz -C /usr/local/ [root@localhost temp]# vim logstatsh_test.conf ======= ...
随机推荐
- javaweb三大框架SSH
1.MVC三层架构:模型层,控制层和视图层.模型层,用Hibernate框架让来JavaBean在数据库生成表及关联,通过对JavaBean的操作来 对数据库进行操作:控制层,用Struts框架来连接 ...
- javascript常用知识汇总
javascript这个语言庞大而复杂,我用了三年多了,还是皮毛都不会.从刚开始的jquery,到后来的es6,每天都在学习,每天都在忘记. 1.禁止手机虚拟键盘弹出 在开发适配手机的页面时,出现了这 ...
- ISBN|方正|超星|The national academies press|OECD|RSC|Springer Link|Knovel|Encyclopedia Britannica
图书使用图书分类号ISBN作为图书的ID 大英百科全书(Encyclopedia Britannica)可用于找寻关键词或关键词相关信息,便于构建准确的检索式: Knovel:可使用物理化学性质查找相 ...
- SHELL的判断括号区别
在使用if语句时,经常会使用().(()).[].[[]].{}等括号,如下为几种括号简单区别对比: ( ) 用于多个命令组.命令替换.初始化数组: (( )) 整数扩展.运算符.重定义变量值,算术运 ...
- sitemesh 使用方法
一.简介 SiteMesh是一个网页布局和修饰的框架,利用它可以将网页的内容和页面结构分离,以达到页面结构共享的目的. 它能通过创建一个包装对象,也就是装饰来包裹的对象.尽管它是由Java语言来实现的 ...
- Twitter类社交平台 用比例建立新的“好坏”与社会焦点
用比例建立新的"好坏"与社会焦点" title="Twitter类社交平台 用比例建立新的"好坏"与社会焦点"> 互联网全面 ...
- JAVA9中文API百度网盘免费下载
JAVA9中文API百度网盘免费下载: https://pan.baidu.com/s/1tvHYQA8yyAS4xUFxwWrx_Q 提取码: 6e5h
- 吴裕雄--天生自然 python开发学习笔记:pycharm无法使用ctrl+c/v复制粘贴的问题
在使用pycharm的时候发现不能正常使用ctrl+c/v进行复制粘贴,也无法使用tab键对大段代码进行整体缩进.后来发现是因为安装了vim插件的问题,在setting里找到vim插件,取消勾选即可解 ...
- 《和莎莫的 500 天》中为什么 Summer 最终没有和 Tom 在一起?
好的电影总是需要仔细赏味几次,每次也都会有不同的收获.就像我钟爱的[500 days of summer]. 彪悍的大胡子导演MarcWebb实在是太有趣,把自己的亲身经历搬上大荧幕,因为" ...
- CSS——NO.7(布局模型)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...