一、概述

  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多数据源分布式事务的分析与解决方案的更多相关文章

  1. C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 VC中进程与进程之间共享内存 .net环境下跨进程、高频率读写数据 使用C#开发Android应用之WebApp 分布式事务之消息补偿解决方案

    C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). ...

  2. Spring Boot2.0之多数据源分布式事务问题

    分布式事务解决方案的问题, 分布式事务产生的原因: 多个不同的服务连接不同的数据源 ,做分布式事务的管理. 这种情况是连接两个数据源的情况,然后事务管理器是这样的 只管理了test02的这端业务代码. ...

  3. spring 多数据源一致性事务方案

    spring 多数据源配置 spring 多数据源配置一般有两种方案: 1.在spring项目启动的时候直接配置两个不同的数据源,不同的sessionFactory.在dao 层根据不同业务自行选择使 ...

  4. SpringBoot 多数据源分布式事务

    1.pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  5. (附源码gitHub下载地址)spring boot -jta-atomikos分布式事务

    应用场景:双数据源,就是某些项目会涉及到两个数据源或者两个以上的数据源,这个多数据源的项目一般是数据同步,也就是把数据从另一个系统中,保存到另一个系统,两边的 数据库又不一样,比如一个Mysql.一个 ...

  6. 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 ...

  7. Spring Cloud Alibaba分布式事务组件 seata 详解(小白都能看懂)

    一,什么是事务(本地事务)? 指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行. 简单的说,事务就是并发控制的单位,是用户定义的一个操作序列.      而一个逻辑工作单元要成 ...

  8. (WebFlux)003、多数据源R2dbc事务失效分析

    一.背景 最近项目持续改造,然后把SpringMVC换成了SpringWebflux,然后把Mybatis换成了R2dbc.中间没有遇到什么问题,一切都那么的美滋滋,直到最近一个新需求的出现,打破了往 ...

  9. ELK(ElasticSearch, Logstash, Kibana) v5.3.2 分布式日志收集分析最佳解决方案 基于CentOS 7 ( 一 )

    [root@localhost temp]# .tar.gz -C /usr/local/ [root@localhost temp]# vim logstatsh_test.conf ======= ...

随机推荐

  1. python学习笔记(9)函数(一)

    定义一个函数 你可以定义一个由自己想要功能的函数,以下是简单的规则: 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 (). 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定 ...

  2. selenium元素定位(一)

    Selenium提供了8种定位方式. id name class name tag name link text partial link text xpath css selector 这8种定位方 ...

  3. spring:事务的5大隔离级别,7大传播行为

    一.五大隔离级别 ISOLATION_READ_UNCOMMITTED:读未提交 ISOLATION_READ_COMMITTED:读已提交 ISOLATION_REPEATABLE_READ:可重复 ...

  4. Mr.Yu

    在linux下搭建Git服务器 git服务器环境 服务器 CentOS7 + git(version 1.8.3.1)客户端 Windows10 + git(version 2.16.0.window ...

  5. FPGA开平方的实现

    3种方法: 1.JPL近似的实现方法 `timescale 1ns / 1ps )( clk, syn_rst, dataa, datab, ampout); input clk; :] dataa; ...

  6. python 3新式类的多继承

    因为我用的是python3,所以所用到的类都是新式类,这里我说的都是新式类,python2类的继承复杂一些,主要有新式类和老式类.python3类(新式类)的继承是是广度优先(BFS),实例如下: c ...

  7. windows下Jmeter压测端口占用问题

    https://blog.csdn.net/weixin_43757847/article/details/88188091 1 前情提要人脸识别项目中,云平台新增了人脸识别的校验接口.考虑到存在大量 ...

  8. c语言函数指针的理解与使用(学习)

    1.函数指针的定义 顾名思义,函数指针就是函数的指针.它是一个指针,指向一个函数.看例子: 1 2 3 A) char * (*fun1)(char * p1,char * p2); B) char  ...

  9. HDU-3579-Hello Kiki (利用拓展欧几里得求同余方程组)

    设 ans 为满足前 n - 1个同余方程的解,lcm是前n - 1个同余方程模的最小公倍数,求前n个同余方程组的解的过程如下: ①设lcm * x + ans为前n个同余方程组的解,lcm * x ...

  10. 关于(Building tool)的认识以及当下流行的Building tool有哪些?

    1.Building tool是什么? (Building tool)构建工具是一种工具,它负责构建流程的所有内容,并自动化与构建项目相关的所有内容.它致力于以下任务: 生成源代码(如果在软件项目中使 ...