美文网首页
spring分布式事务实现

spring分布式事务实现

作者: IT职业与自媒体思考 | 来源:发表于2020-07-05 21:49 被阅读0次

大型应用中,会有如下的情况,Peter老师希望大家能考虑到,这个比较符合实际情况。

当数据量越来越多的时候,我们就会开始考虑跨库查询,读写分离,之前对于数据库读写分离有过一定的了解,但是这里面存在着一个问题,就是A库中有a表,B库中有b表,那如果b表出现了异常,a表这个时候怎么回滚呢?当在一个数据库中直接用事务很好的处理,那如果在多个数据源中呢?其实原理是一样的。

对于一些较大的规模的应用,单个数据源已经无法支撑起庞大的用户量,需要引入多数据源,水平层面进行分库分表,降低DB的负载。另外,跨库意味着单DB的事务就失效了,所以J2EE提出了JTA,分布式事务管理,简单的说,就是分2步提交,实际它有2个容器来管理,一个资源管理器,一个事务管理,在第一个阶段中,所有参与全局事务的节点都开始准备,告诉事务管理器它们准备好提交了。第二阶段,事务管理器告诉资源管理器执行commit或者rollback,如果任何一个节点显示不能commit,那么所有的节点全部rollback,下面我们来实现分布式事务:

XA协议是分布事务处理中子事务与全局事务间通讯的接口规范。

第一步:XA数据源定义

     选定义一个抽象的父类源,这样子类可以直接继承

<!-- 两个数据源的功用配置,方便下面直接引用 -->

<bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"      destroy-method="close">

<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>

<property name="poolSize" value="10" />

<property name="minPoolSize" value="10"/>

<property name="maxPoolSize" value="30"/>

<property name="borrowConnectionTimeout" value="60"/>

<property name="reapTimeout" value="20"/>

<!-- 最大空闲时间 -->    

<property name="maxIdleTime" value="60"/>

<property name="maintenanceInterval" value="60" />

<property name="loginTimeout" value="60"/>

<property name="logWriter" value="60"/>

<property name="testQuery">

<value>select 1</value>

</property>

</bean>

 master源

<bean id="masterSource" parent="abstractXADataSource">    <property name="uniqueResourceName">        <value>master</value>    </property>    <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />    <property name="xaProperties">        <props>            <prop key="user">库用户名</prop>            <prop key="password">库密码</prop>            <prop key="URL">master库连接</prop>        </props>    </property></bean>

slave源

<bean id="slaveSource" parent="abstractXADataSource">    <property name="uniqueResourceName">        <value>slave</value>    </property>    <property name="xaDataSourceClassName">        <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>    </property>    <property name="xaProperties">        <props>            <prop key="user">库用户名</prop>            <prop key="password">库密码</prop>            <prop key="URL">slave库连接</prop>        </props>    </property></bean>

基于spring的AbstractRoutingDataSource动态数据路由定义

<bean id="dataSource" class="com.icz.carcare.datasource.DynamicDataSource"><property name="targetDataSources"><map key-type="java.lang.String"><!-- write 数据更新和实时数据查询-->            <entry key="master" value-ref="masterSource"/><!-- read 非实时数据查询-->            <entry key="slave" value-ref="slaveSource"/></map></property><property name="defaultTargetDataSource" ref="masterSource"/><!-- 默认使用master的数据源 --></bean>

mybatis中进行ORM映射

<bean id="sqlSessionFactorya" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="masterSource"/><!-- 自动扫描sqlmaps目录, 省掉Configuration.xml里的手工配置 -->    <property name="mapperLocations" value="classpath*:Msqlmaps/*.xml" /></bean><bean id="sqlSessionFactoryb" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="slaveSource" /><!-- 自动扫描sqlmaps目录, 省掉Configuration.xml里的手工配置 -->    <property name="mapperLocations" value="classpath*:Msqlmaps/*.xml" /></bean>

配置sessionTemplate模板

<!-- 配置自定义的SqlSessionTemplate模板,注入相关配置 --><bean id="sqlSessionTemplate" class="com.icz.carcare.sqlSessionTemplate.CustomSqlSessionTemplate"><constructor-arg ref="sqlSessionFactorya" /><property name="targetSqlSessionFactorys"><map><entry value-ref="sqlSessionFactorya" key="master"/><entry value-ref="sqlSessionFactoryb" key="slave"/></map></property></bean>

jta配置

<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"      init-method="init" destroy-method="close"><property name="forceShutdown"><value>true</value></property></bean><bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"><property name="transactionTimeout" value="300" /></bean><bean id="springTransactionManager"      class="org.springframework.transaction.jta.JtaTransactionManager"><property name="transactionManager"><ref bean="atomikosTransactionManager" /></property><property name="userTransaction"><ref bean="atomikosUserTransaction" /></property></bean>

以上xml配置完了,现在就可以去实现跨库事务的代码编写了。

下面我们来讲讲分布式事务原理理解。

Innodb存储引擎支持XA事务,通过XA事务可以支持分布式事务的实现。分布式事务指的是允许多个独立的事务资源参与一个全局事务中。

全局事务要求其中所参与的事务要么提交,要么全部回滚。

XA事务允许不同数据库之间的分布式事务,如:一台服务器是Mysql数据库,一台是Oracle的,又有可能还有一台是sqlserver的,只要参与全部事务中每个节点都支持XA事务。分布式事务可能在银行系统的转账中比较常见,

#bank shanghai

update user_account set money=money+100 where user='xiaozhang';

#bank beijing

update user_account set money=money-100 where user='xiaoli';

像这种情况就是,要不都提交,要不都回滚。在任何一个节点出问题都会造成严重的问题,1 xiaozhang的账号收到了钱,但是xiaoli没有扣款 2.xiaozhang的账号没有收到钱,但是xiaoli扣款了

分布式事务是由一个或者多个resource Managerd,一个事务管理器transaction manage以及一个应用程序application Program组成。

资源管理器:提供事务资源的方法,通常一个数据库就是一个资源管理器

事务管理器:协调参与全部事务各个事务,需要和参与全局事务中的资源管理员进行通信。

应用程序:定义事务的边界,指定全局事务中的操作。

在mysql分布式事务中,资源管理器就是mysql数据库,事务管理器为连接到mysql服务器的客户端

相关文章

  • Spring Cloud Alibaba(6.2 Seata——

    一、概述 本文,我们将纯 Spring Boot应用接入 Seata 来实现分布式事务,后续介绍Spring Cl...

  • [七]分布式事务

    JTA实现分布式事务 使用Spring boot JTA 可以使用如Jboss之类的应用服务器提供的JTA事务管...

  • Spring事务

    Spring 事务 分类 Spring可以支持编程式事务和声明式事务。 编程式事务 实现 Spring使用事务管理...

  • spring04

    Spring JdbcTemplate学习 Spring 声明式事务 xml配置实现 Spring 声明式事务 注...

  • Spring中实现事务方式

    Spring 中实现事务的方式 Spring 并不直接支持事务,只有当数据库支持事务时,Spring 才支持事务,...

  • Spring 事务实现分析

    1. Spring 事务简介 Spring 本身并不实现事务,Spring事务 的本质 还是 底层数据库 对事务的...

  • SSM spring 2

    1 Spring 事务实现方式、事务的传播机制、默认的事务类别 Spring事务的1+3种实现方式、7种传播行为、...

  • Mysql基础——事务

    内容 事务事务基本知识事务特性如何实现的?快照读和当前读 分布式事务XA规范mysql基于XA实现的分布式事务my...

  • 程序员之Spring

    1. Spring事务 spring的事务实现原理Spring事务将connection放入到当前线程的threa...

  • MySQL分布式事务支持

    MySQL分布式事务介绍 InnoDB存储引擎提供了对XA事务的支持,并通过XA事务来支持分布式事务的实现。分布式...

网友评论

      本文标题:spring分布式事务实现

      本文链接:https://www.haomeiwen.com/subject/swebqktx.html