在开发中,为了降低单点压力,通常会根据业务情况进行分表分库,将表分布在不同的库中(库可能分布在不同的机器上)。在这种场景下,事务的提交会变得相对复杂,因为多个节点(库)的存在,可能存在部分节点提交失败的情况,即事务的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相关推荐

  1. mysql 事物的持久性是指_详解MySQL中事务的持久性实现原理

    前言 说到数据库事务,大家脑子里一定很容易蹦出一堆事务的相关知识,如事务的ACID特性,隔离级别,解决的问题(脏读,不可重复读,幻读)等等,但是可能很少有人真正的清楚事务的这些特性又是怎么实现的,为什 ...

  2. 分布式事务详解【分布式事务的几种解决方案】彻底搞懂分布式事务

    文章目录 一.基本概念 什么是事务 本地事务 分布式事务 分布式事务产生的场景 二.分布式事务基础理论 CAP理论 CP - Consistency/Partition Tolerance AP - ...

  3. 详解MySQL之事务

    事务 事务的组成可由一条非常简单的SQL语句组成,也可由一组复杂的SQL语句组成. 特征 事务具有以下特征: (1)在数据提交时,可以确保要么所有修改都已保存,要么所有修改不保存: (2)事务是访问并 ...

  4. 一文详解,分布式事务Seata

    事务ACID原则 原子性:事务中的所有操作,要么全部成功,要么全部失败一致性:要保证数据库内部完整性约束.声明性约束隔离性:对同一资源操作的事务不能同时发生持久性:对数据库做的一切修改将永久保存,不管 ...

  5. mysql执行事务的语句_详解MySQL执行事务的语法和流程

    摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...

  6. RocketMQ的Producer详解之分布式事务消息(回顾事务)

    回顾什么事务 聊什么是事务,最经典的例子就是转账操作,用户A转账给用户B1000元的过程如下: 用户A发起转账请求,用户A账户减去1000元 用户B的账户增加1000元 如果,用户A账户减去1000元 ...

  7. 详解MySQL执行事务的语法和流程

    摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...

  8. 详解mysql事务_详解MySQL执行事务的语法和流程

    摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...

  9. 一文详解Mysql锁事务隔离级别

    一.锁的定义 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除了传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供需要用户共 享的资源.如何保证数据并发访问的一致 ...

最新文章

  1. Java、Python、Go 哪个后端编程语言适合web前端工程师学习?
  2. powerdesigner逆向工程,从数据库导出PDM
  3. 如何找GitHub上热门的开源项目
  4. net start mysql 发生系统错误2 系统找不到指定的文件
  5. 单链表删除所有值为x的元素_线性表之单链表
  6. android 机顶盒 view 焦点,AndroidTV/机顶盒 ListView获取焦点与点击事件问题处理方案...
  7. 最简单的Jdbc连接Oracle代码
  8. websocket连接相关的几个问题
  9. 香橙派进入系统后设置ip
  10. Operator基础:3: 使用Operator SDK创建Operator
  11. 房屋租赁合同无效条件包括哪些
  12. 睡眠 应该用 a加权 c加权_CPA每日一练财管加权平均资本成本的计算
  13. “钢铁侠”把特斯拉送上太空,可你知道发射卫星有多难吗?
  14. 数据分析实战:航空公司客户价值分析
  15. Js 高德地图SDK
  16. 【SayGoodBye.java】一封离职告别信
  17. 个人简历网站的数据库设计方案
  18. 柏拉图對愛與婚姻得啟示---------捷徑穿越人生得麦田
  19. CUDA编程--邻近点查询
  20. Web3.0 兴起,元宇宙或接管互联网?

热门文章

  1. mysql最左前缀概念_mysql查询优化之目录类型、最左前缀
  2. STC51从入门到精通(汇编)~~~ 第三讲:MCS-51单片机的结构和工作原理
  3. 【hbase问题】org.apache.hadoop.hbase.ipc.ServerNotRunningYetException: Server is not run
  4. css编辑器推荐-Stylizer 与 Stylizer破解
  5. 用计算机怎么管理小米路由器,怎样用手机设定小米路由器
  6. QT半透明图片叠加显示
  7. html3d粒子球,Canvas粒子系统:3D球体
  8. module ‘win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9‘ has no attribute ‘CLSIDToClassM
  9. 部署Python的框架下的web app的详细教程
  10. (附源码)计算机毕业设计SSM驾校预约考试管理系统