详解Mysql分布式事务XA
在开发中,为了降低单点压力,通常会根据业务情况进行分表分库,将表分布在不同的库中(库可能分布在不同的机器上)。在这种场景下,事务的提交会变得相对复杂,因为多个节点(库)的存在,可能存在部分节点提交失败的情况,即事务的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%'
- 1
- 1
如果innodb_support_xa的值是ON就说明mysql已经开启对XA事务的支持了。
如果不是就执行:
SET innodb_support_xa = ON
- 1
- 1
开启
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'");//准备事务2try {//$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();?>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
XA的性能问题
XA的性能很低。一个数据库的事务和多个数据库间的XA事务性能对比可发现,性能差10倍左右。因此要尽量避免XA事务,例如可以将数据写入本地,用高性能的消息系统分发数据。或使用数据库复制等技术。只有在这些都无法实现,且性能不是瓶颈时才应该使用XA。
详解Mysql分布式事务XA相关推荐
- mysql 事物的持久性是指_详解MySQL中事务的持久性实现原理
前言 说到数据库事务,大家脑子里一定很容易蹦出一堆事务的相关知识,如事务的ACID特性,隔离级别,解决的问题(脏读,不可重复读,幻读)等等,但是可能很少有人真正的清楚事务的这些特性又是怎么实现的,为什 ...
- 分布式事务详解【分布式事务的几种解决方案】彻底搞懂分布式事务
文章目录 一.基本概念 什么是事务 本地事务 分布式事务 分布式事务产生的场景 二.分布式事务基础理论 CAP理论 CP - Consistency/Partition Tolerance AP - ...
- 详解MySQL之事务
事务 事务的组成可由一条非常简单的SQL语句组成,也可由一组复杂的SQL语句组成. 特征 事务具有以下特征: (1)在数据提交时,可以确保要么所有修改都已保存,要么所有修改不保存: (2)事务是访问并 ...
- 一文详解,分布式事务Seata
事务ACID原则 原子性:事务中的所有操作,要么全部成功,要么全部失败一致性:要保证数据库内部完整性约束.声明性约束隔离性:对同一资源操作的事务不能同时发生持久性:对数据库做的一切修改将永久保存,不管 ...
- mysql执行事务的语句_详解MySQL执行事务的语法和流程
摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...
- RocketMQ的Producer详解之分布式事务消息(回顾事务)
回顾什么事务 聊什么是事务,最经典的例子就是转账操作,用户A转账给用户B1000元的过程如下: 用户A发起转账请求,用户A账户减去1000元 用户B的账户增加1000元 如果,用户A账户减去1000元 ...
- 详解MySQL执行事务的语法和流程
摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...
- 详解mysql事务_详解MySQL执行事务的语法和流程
摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...
- 一文详解Mysql锁事务隔离级别
一.锁的定义 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除了传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供需要用户共 享的资源.如何保证数据并发访问的一致 ...
最新文章
- Java、Python、Go 哪个后端编程语言适合web前端工程师学习?
- powerdesigner逆向工程,从数据库导出PDM
- 如何找GitHub上热门的开源项目
- net start mysql 发生系统错误2 系统找不到指定的文件
- 单链表删除所有值为x的元素_线性表之单链表
- android 机顶盒 view 焦点,AndroidTV/机顶盒 ListView获取焦点与点击事件问题处理方案...
- 最简单的Jdbc连接Oracle代码
- websocket连接相关的几个问题
- 香橙派进入系统后设置ip
- Operator基础:3: 使用Operator SDK创建Operator
- 房屋租赁合同无效条件包括哪些
- 睡眠 应该用 a加权 c加权_CPA每日一练财管加权平均资本成本的计算
- “钢铁侠”把特斯拉送上太空,可你知道发射卫星有多难吗?
- 数据分析实战:航空公司客户价值分析
- Js 高德地图SDK
- 【SayGoodBye.java】一封离职告别信
- 个人简历网站的数据库设计方案
- 柏拉图對愛與婚姻得啟示---------捷徑穿越人生得麦田
- CUDA编程--邻近点查询
- Web3.0 兴起,元宇宙或接管互联网?
热门文章
- mysql最左前缀概念_mysql查询优化之目录类型、最左前缀
- STC51从入门到精通(汇编)~~~ 第三讲:MCS-51单片机的结构和工作原理
- 【hbase问题】org.apache.hadoop.hbase.ipc.ServerNotRunningYetException: Server is not run
- css编辑器推荐-Stylizer 与 Stylizer破解
- 用计算机怎么管理小米路由器,怎样用手机设定小米路由器
- QT半透明图片叠加显示
- html3d粒子球,Canvas粒子系统:3D球体
- module ‘win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9‘ has no attribute ‘CLSIDToClassM
- 部署Python的框架下的web app的详细教程
- (附源码)计算机毕业设计SSM驾校预约考试管理系统