文档章节

详解Mysql分布式事务XA(跨数据库事务)

沉淀岁月
 沉淀岁月
发布于 2017/09/04 20:49
字数 1512
阅读 27
收藏 0
点赞 0
评论 0

在开发中,为了降低单点压力,通常会根据业务情况进行分表分库,将表分布在不同的库中(库可能分布在不同的机器上)。在这种场景下,事务的提交会变得相对复杂,因为多个节点(库)的存在,可能存在部分节点提交失败的情况,即事务的ACID特性需要在各个不同的数据库实例中保证。比如更新db1库的A表时,必须同步更新db2库的B表,两个更新形成一个事务,要么都成功,要么都失败。 
那么我们如何利用MySQL实现分布式数据库的事务呢?

MySQL 5.7为我们提供了分布式事务解决方案(https://dev.mysql.com/doc/refman/5.7/en/xa.html) 
这里先声明两个概念:

  • 资源管理器(resource manager):用来管理系统资源,是通向事务资源的途径。数据库就是一种资源管理器。资源管理还应该具有管理事务提交或回滚的能力。
  • 事务管理器(transaction manager):事务管理器是分布式事务的核心管理者。事务管理器与每个资源管理器(resource 
    manager)进行通信,协调并完成事务的处理。事务的各个分支由唯一命名进行标识。

mysql在执行分布式事务(外部XA)的时候,mysql服务器相当于xa事务资源管理器,与mysql链接的客户端相当于事务管理器。

分布式事务原理:分段式提交

分布式事务通常采用2PC协议,全称Two Phase Commitment Protocol。该协议主要为了解决在分布式数据库场景下,所有节点间数据一致性的问题。分布式事务通过2PC协议将提交分成两个阶段:

  • prepare;
  • commit/rollback

阶段一为准备(prepare)阶段。即所有的参与者准备执行事务并锁住需要的资源。参与者ready时,向transaction manager报告已准备就绪。 
阶段二为提交阶段(commit)。当transaction manager确认所有参与者都ready后,向所有参与者发送commit命令。 
如下图所示: 
这里写图片描述

事务协调者transaction manager

因为XA 事务是基于两阶段提交协议的,所以需要有一个事务协调者(transaction manager)来保证所有的事务参与者都完成了准备工作(第一阶段)。如果事务协调者(transaction manager)收到所有参与者都准备好的消息,就会通知所有的事务都可以提交了(第二阶段)。MySQL 在这个XA事务中扮演的是参与者的角色,而不是事务协调者(transaction manager)。

Mysql的XA事务分为外部XA和内部XA

  • 外部XA用于跨多MySQL实例的分布式事务,需要应用层作为协调者,通俗的说就是比如我们在PHP中写代码,那么PHP书写的逻辑就是协调者。应用层负责决定提交还是回滚,崩溃时的悬挂事务。MySQL数据库外部XA可以用在分布式数据库代理层,实现对MySQL数据库的分布式事务支持,例如开源的代理工具:网易的DDB,淘宝的TDDL等等。
  • 内部XA事务用于同一实例下跨多引擎事务,由Binlog作为协调者,比如在一个存储引擎提交时,需要将提交信息写入二进制日志,这就是一个分布式内部XA事务,只不过二进制日志的参与者是MySQL本身。Binlog作为内部XA的协调者,在binlog中出现的内部xid,在crash recover时,由binlog负责提交。(这是因为,binlog不进行prepare,只进行commit,因此在binlog中出现的内部xid,一定能够保证其在底层各存储引擎中已经完成prepare)。

MySQL XA事务基本语法

XA {START|BEGIN} xid [JOIN|RESUME] 启动xid事务 (xid 必须是一个唯一值; 不支持[JOIN|RESUME]子句) 
XA END xid [SUSPEND [FOR MIGRATE]] 结束xid事务 ( 不支持[SUSPEND [FOR MIGRATE]] 子句) 
XA PREPARE xid 准备、预提交xid事务 
XA COMMIT xid [ONE PHASE] 提交xid事务 
XA ROLLBACK xid 回滚xid事务 
XA RECOVER 查看处于PREPARE 阶段的所有事务

PHP调用MYSQL XA事务示例

1、首先要确保mysql开启XA事务支持

SHOW VARIABLES LIKE '%xa%'
  •  

如果innodb_support_xa的值是ON就说明mysql已经开启对XA事务的支持了。 
如果不是就执行:

SET innodb_support_xa = ON
  •  

开启

2、代码如下:

<?PHP
$dbtest1 = new mysqli("172.20.101.17","public","public","dbtest1")or die("dbtest1 连接失败");
$dbtest2     = new mysqli("172.20.101.18","public","public","dbtest2")or die("dbtest2 连接失败");

//为XA事务指定一个id,xid 必须是一个唯一值。
$xid = uniqid("");

//两个库指定同一个事务id,表明这两个库的操作处于同一事务中
$dbtest1->query("XA START '$xid'");//准备事务1
$dbtest2->query("XA START '$xid'");//准备事务2

try {
    //$dbtest1
    $return = $dbtest1->query("UPDATE member SET name='唐大麦' WHERE id=1") ;
    if($return == false) {
       throw new Exception("库dbtest1@172.20.101.17执行update member操作失败!");
    }

    //$dbtest2
    $return = $dbtest2->query("UPDATE memberpoints SET point=point+10 WHERE memberid=1") ;
    if($return == false) {
       throw new Exception("库dbtest1@172.20.101.18执行update memberpoints操作失败!");
    }

    //阶段1:$dbtest1提交准备就绪
    $dbtest1->query("XA END '$xid'");
    $dbtest1->query("XA PREPARE '$xid'");
    //阶段1:$dbtest2提交准备就绪
    $dbtest2->query("XA END '$xid'");
    $dbtest2->query("XA PREPARE '$xid'");

    //阶段2:提交两个库
    $dbtest1->query("XA COMMIT '$xid'");
    $dbtest2->query("XA COMMIT '$xid'");
} 
catch (Exception $e) {
    //阶段2:回滚
    $dbtest1->query("XA ROLLBACK '$xid'");
    $dbtest2->query("XA ROLLBACK '$xid'");
    die($e->getMessage());
}

$dbtest1->close();
$dbtest2->close();

?>
  •  

XA的性能问题

XA的性能很低。一个数据库的事务和多个数据库间的XA事务性能对比可发现,性能差10倍左右。因此要尽量避免XA事务,例如可以将数据写入本地,用高性能的消息系统分发数据。或使用数据库复制等技术。只有在这些都无法实现,且性能不是瓶颈时才应该使用XA。

本文转载自:http://blog.csdn.net/lmjy102/article/details/72673297

共有 人打赏支持
沉淀岁月
粉丝 25
博文 252
码字总数 91615
作品 0
朝阳
高级程序员
干货|一篇文章带你学习分布式事务

小蚂蚁说: 分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在这几年越来越火的微服务架构中,几乎可以说是无法避免,本文就围绕分布式事务...

兔子酱 ⋅ 05/28 ⋅ 0

MySQL binlog 组提交与 XA(两阶段提交)

1. XA-2PC (two phase commit, 两阶段提交 ) XA是由X/Open组织提出的分布式事务的规范(X代表transaction; A代表accordant?)。XA规范主要定义了(全局)事务管理器(TM: Transaction Manager)和...

Jenkin_lin ⋅ 2017/03/23 ⋅ 0

MySQL · 特性分析 · 浅谈 MySQL 5.7 XA 事务改进

关于MySQL XA 事务 MySQL XA 事务通常用于分布式事务处理当中。比如在分库分表的场景下,当遇到一个用户事务跨了多个分区,需要使用XA事务 来完成整个事务的正确的提交和回滚,即保证全局事务...

阿里云RDS-数据库内核组 ⋅ 2017/09/06 ⋅ 0

分布式事务系列(4.1)Atomikos的分布式案例

1 系列目录 - 分布式事务系列(开篇)提出疑问和研究过程- 分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager源码分析- 分布式事务系列(1.2)Spring事务体系- 分布式事务系...

乒乓狂魔 ⋅ 2015/06/01 ⋅ 3

【分布式事务系列七】Atomikos的分布式案例

分布式事务 【分布式事务系列一】提出疑问和研究过程 【分布式事务系列二】Spring事务管理器PlatformTransactionManager 【分布式事务系列三】Spring的事务体系 【分布式事务系列四】分布式事...

陶邦仁 ⋅ 2015/12/21 ⋅ 0

数据库中间件 MyCAT 源码分析 —— XA分布式事务

wechat_mp 🙂🙂🙂关注微信公众号有福利: RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表 RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址 您对于源码的疑问每条...

芋道源码掘金Java群217878901 ⋅ 2017/07/16 ⋅ 0

【开源访谈】网易开源数据库中间件 Cetus 如何让 MySQL 更强大?

电商系统中,随着业务量的增大,读写 QPS 越来越高,单节点 MySQL 实例压力越来越大,单纯的对服务器硬件升级已经无法满足生产环境的需要,对数据分片增加多个节点,降低单节点 MySQL 实例的...

雨田桑 ⋅ 04/16 ⋅ 6

五年磨一剑、16项核心专利, GTS为分布式事务带来哪些全新定义?

在企业级互联网架构专场中,来自阿里巴巴的中间件技术专家厉启鹏(寈峰)为现场的听众带来了题为《GTS-分布式事务全新解决方案》的精彩分享。在本次分享中,他重点阐述了GTS如何帮助解决分布...

云迹九州 ⋅ 06/08 ⋅ 0

深入理解分布式事务

Spring事务本质是单机下的事务,是由数据库本身保证的。今天,我将介绍一种比较复杂的事务:分布式事务。 1 什么是分布式事务 分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以...

小车车 ⋅ 2016/08/10 ⋅ 0

深入理解分布式事务

Spring事务本质是单机下的事务,是由数据库本身保证的。今天,我将介绍一种比较复杂的事务:分布式事务。 1.什么是分布式事务 分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以...

xboy_ly ⋅ 2016/08/25 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具

压缩打包介绍 使用压缩工具的好处: 使用压缩文件,不仅可以节省磁盘空间,而且在传输时还能节省网络宽带。 我们通常讲的家用宽带和机房宽带100M是有区别的: 机房宽带的上行和下行都是100M,...

Linux_老吴 ⋅ 29分钟前 ⋅ 0

SpringBoot热部署加持

概述 进行SpringBoot的Web开发过程中,我们很多时候经常需要重启Web服务器才能保证修改的 源代码文件、或者一些诸如xml的配置文件、以及一些静态文件生效,这样耗时又低效。所谓的热部署指的...

CodeSheep ⋅ 35分钟前 ⋅ 0

OSChina 周六乱弹 —— 假如你被熊困到树上

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲《如果写不出好的和弦就该在洒满阳光的钢琴前一起吃布丁》 《如果写不出好的和弦就该在洒满阳光的钢琴前一起吃布丁》- 谢...

小小编辑 ⋅ 今天 ⋅ 5

vbs 取文件大小 字节

dim namedim fs, s'name = Inputbox("姓名")'msgbox(name)set fs = wscript.createobject("scripting.filesystemobject") 'fs为FSO实例if (fs.folderexists("c:\temp"))......

vga ⋅ 今天 ⋅ 1

高并发之Nginx的限流

首先Nginx的版本号有要求,最低为1.11.5 如果低于这个版本,在Nginx的配置中 upstream web_app { server 到达Ip1:端口 max_conns=10; server 到达Ip2:端口 max_conns=10; } server { listen ...

算法之名 ⋅ 今天 ⋅ 0

Spring | IOC AOP 注解 简单使用

写在前面的话 很久没更新笔记了,有人会抱怨:小冯啊,你是不是在偷懒啊,没有学习了。老哥,真的冤枉:我觉得我自己很菜,还在努力学习呢,正在学习Vue.js做管理系统呢。即便这样,我还是不...

Wenyi_Feng ⋅ 今天 ⋅ 0

博客迁移到 https://www.jianshu.com/u/aa501451a235

博客迁移到 https://www.jianshu.com/u/aa501451a235 本博客不再更新

为为02 ⋅ 今天 ⋅ 0

win10怎么彻底关闭自动更新

win10自带的更新每天都很多,每一次下载都要占用大量网络,而且安装要等得时间也蛮久的。 工具/原料 Win10 方法/步骤 单击左下角开始菜单点击设置图标进入设置界面 在设置窗口中输入“服务”...

阿K1225 ⋅ 今天 ⋅ 0

Elasticsearch 6.3.0 SQL功能使用案例分享

The best elasticsearch highlevel java rest api-----bboss Elasticsearch 6.3.0 官方新推出的SQL检索插件非常不错,本文一个实际案例来介绍其使用方法。 1.代码中的sql检索 @Testpu...

bboss ⋅ 今天 ⋅ 0

informix数据库在linux中的安装以及用java/c/c++访问

一、安装前准备 安装JDK(略) 到IBM官网上下载informix软件:iif.12.10.FC9DE.linux-x86_64.tar放在某个大家都可以访问的目录比如:/mypkg,并解压到该目录下。 我也放到了百度云和天翼云上...

wangxuwei ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部