分布式事务实战---XA两阶段提交(2PC)方案详解(上)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 分布式事务实战---XA两阶段提交(2PC)方案详解

XA,2PC,two-phase commit protocol,两阶段事务提交采⽤的是 X/OPEN 组织定义的DTP 模型所抽象的:

  • AP
    应用程序,Application Program,定义事务边界(即定义事务的开始和结束),并且在事务边界内对资源进行操作
  • TM(事务管理器)
    Transaction Manager,负责分配事务唯一标识,监控事务的执行进度,并负责事务的提交、回滚等
  • RM(资源管理器)
    Resource Manager,如数据库、文件系统等,并提供访问资源的方式

XA 接口

xa_start :负责开启或者恢复一个事务分支

xa_end: 负责取消当前线程与事务分支的关联

xa_prepare:询问 RM 是否准备好提交事务分支

xa_commit:通知 RM 提交事务分支

xa_rollback: 通知 RM 回滚事务分支

xa_recover : 需要恢复的 XA 事务

1.png

保证分布式事务的强⼀致性。其中 TM 与 RM 间采⽤ XA 协议进⾏双向通信。

XA 整体设计思路可概括为:在现有事务模型基础上微调扩展而实现的分布式事务。


与传统的本地事务相⽐,XA 事务增加了准备阶段,数据库除了被动接受提交指令外,还可以反向通知调⽤⽅事务是否可以被提交。TM 可以收集所有分⽀事务的准备结果,并于最后进⾏原⼦提交,以保证事务的强⼀致性

  • 两阶段提交模型

image.png

  • Java 通过定义 JTA 接口实现了 XA 模型

image.png

JTA 接口中的 ResourceManager 需要数据库⼚商提供 XA 驱动实现,TransactionManager 则需要事务管理器的⼚商实现,传统的事务管理器需要同应⽤服务器绑定,因此使⽤的成本很⾼。而嵌⼊式的事务管器可以以 jar 包的形式提供服务,同 Apache ShardingSphere集成后,可保证分⽚后跨库事务强⼀致性。通常,只有使⽤了事务管理器⼚商所提供的 XA 事务连接池,才能⽀持 XA 的事务。Apache ShardingSphere在整合 XA 事务时,采⽤分离 XA 事务管理和连接池管理的⽅式,做到对应⽤程序的零侵⼊。


MySQL 从5.0.3开始支持 InnoDB 引擎的 XA 分布式事务,MySQL Connector/J 从5.0.0版本开始支持 XA。

image.png

在 DTP 模型中,MySQL 属于资源管理器(RM)。分布式事务中存在多个 RM,由事务管理器 TM 来统一进行协调。

image.png

MySQL 的 XA

  • XA {START | BEGIN} xid [JOIN | RESUME]
    开启XA事务,如果使用的是XA START而非XA BEGIN,那么不支持[JOIN | RESUME],xid是个唯一值,表示事务分支标
    全局 + 分支 id

image.png

  • XA END xid [SUSPEND [FOR MIGRATE]]
    结束一个xA事务,不支持[SUSPEND [FOR MIGRATE]]
  • XA PREPARE xid

准备提交

  • XA COMIT xid [ONE PHASE]
    提交,如果使用了 ONE PHASE,贼表示使用一阶段提交。两阶段提交协议中,如果只有一个 RM 参与,那么可以优化为一阶段提交
  • XA ROLLBACK xid

image.png

回滚

  • XA recover[convert xid]

image.png

列出所有处于 prepare 阶段的 XA 事务

mysql> select * from t;
+----+------+------+
| id | c    | d    |
+----+------+------+
|  0 |    0 |    0 |
|  5 |    5 |    5 |
| 10 |   10 |   10 |
| 15 |   15 |   15 |
| 20 |   20 |   20 |
| 25 |   25 |   25 |
| 30 |   10 |   30 |
+----+------+------+
7 rows in set (0.01 sec)
mysql> xa start 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t values(1,2,3);
Query OK, 1 row affected (0.01 sec)
mysql> update t set id = 11 where id = 10;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> xa end 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> xa prepare 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> xa commit 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t;
+----+------+------+
| id | c    | d    |
+----+------+------+
|  0 |    0 |    0 |
|  1 |    2 |    3 | # 添加的记录
|  5 |    5 |    5 |
| 11 |   10 |   10 | # 修改的记录
| 15 |   15 |   15 |
| 20 |   20 |   20 |
| 25 |   25 |   25 |
| 30 |   10 |   30 |
+----+------+------+
8 rows in set (0.01 sec)
mysql> xa start 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t values(2,5,8);
Query OK, 1 row affected (0.00 sec)
mysql> xa end 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> xa prepare 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> xa recover;
# gtr 全局事务 id
# bq 分支事务 id,这就能区分是大事务,还是小事务
+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
|        1 |            3 |            0 | x01  |
+----------+--------------+--------------+------+
1 row in set (0.00 sec)
mysql> xa start 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t values(2,5,8);
Query OK, 1 row affected (0.00 sec)
mysql> xa end 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> xa prepare 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> xa recover;
+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
|        1 |            3 |            0 | x01  |
+----------+--------------+--------------+------+
1 row in set (0.00 sec)
mysql> xa rollback 'x01';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t;
+----+------+------+
| id | c    | d    |
+----+------+------+
|  0 |    0 |    0 |
|  1 |    2 |    3 |
|  5 |    5 |    5 |
| 11 |   10 |   10 |
| 15 |   15 |   15 |
| 20 |   20 |   20 |
| 25 |   25 |   25 |
| 30 |   10 |   30 |
+----+------+------+
8 rows in set (0.00 sec)
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
12天前
|
NoSQL 算法 关系型数据库
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
本文详解分布式全局唯一ID及其5种实现方案,关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式 ID 详解 ( 5大分布式 ID 生成方案 )
|
20天前
|
存储 缓存 NoSQL
分布式架构下 Session 共享的方案
【10月更文挑战第15天】在实际应用中,需要根据具体的业务需求、系统架构和性能要求等因素,选择合适的 Session 共享方案。同时,还需要不断地进行优化和调整,以确保系统的稳定性和可靠性。
|
26天前
|
NoSQL Java Redis
开发实战:使用Redisson实现分布式延时消息,订单30分钟关闭的另外一种实现!
本文详细介绍了 Redisson 延迟队列(DelayedQueue)的实现原理,包括基本使用、内部数据结构、基本流程、发送和获取延时消息以及初始化延时队列等内容。文章通过代码示例和流程图,逐步解析了延迟消息的发送、接收及处理机制,帮助读者深入了解 Redisson 延迟队列的工作原理。
|
29天前
|
SQL NoSQL 安全
分布式环境的分布式锁 - Redlock方案
【10月更文挑战第2天】Redlock方案是一种分布式锁实现,通过在多个独立的Redis实例上加锁来提高容错性和可靠性。客户端需从大多数节点成功加锁且总耗时小于锁的过期时间,才能视为加锁成功。然而,该方案受到分布式专家Martin的质疑,指出其在特定异常情况下(如网络延迟、进程暂停、时钟偏移)可能导致锁失效,影响系统的正确性。Martin建议采用fencing token方案,以确保分布式锁的正确性和安全性。
37 0
|
3月前
|
存储 NoSQL Java
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
这篇文章是关于Java面试中的分布式架构问题的笔记,包括分布式架构下的Session共享方案、RPC和RMI的理解、分布式ID生成方案、分布式锁解决方案以及分布式事务解决方案。
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
|
3月前
|
消息中间件 Java Kafka
"Kafka快速上手:从环境搭建到Java Producer与Consumer实战,轻松掌握分布式流处理平台"
【8月更文挑战第10天】Apache Kafka作为分布式流处理平台的领头羊,凭借其高吞吐量、可扩展性和容错性,在大数据处理、实时日志收集及消息队列领域表现卓越。初学者需掌握Kafka基本概念与操作。Kafka的核心组件包括Producer(生产者)、Broker(服务器)和Consumer(消费者)。Producer发送消息到Topic,Broker负责存储与转发,Consumer则读取这些消息。首先确保已安装Java和Kafka,并启动服务。接着可通过命令行创建Topic,并使用提供的Java API实现Producer发送消息和Consumer读取消息的功能。
69 8
|
3月前
|
消息中间件 SQL 关系型数据库
go-zero微服务实战系列(十、分布式事务如何实现)
go-zero微服务实战系列(十、分布式事务如何实现)
|
3月前
|
存储 运维 安全
多云网络部署存在挑战,F5分布式云应用简化方案解读
多云网络部署存在挑战,F5分布式云应用简化方案解读
47 0
|
25天前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?

热门文章

最新文章

下一篇
无影云桌面