分布式事务(一)
分布式事务
介绍
最近遇到了一个业务场景,需要做一个工具,将两个业务写数据库合并到一个读数据库。在读写过程中需要做跨库的事务操作,也就是分布式事务。简单来说,就是要同时往两个数据库写数据,要求这个写操作要作为一个事务。
于是学习了一些分布式事务的知识,做一下汇总。
分布式事务解决方案
主要有以下几种的解决方案:
- XA事务/两阶段提交(2PC)
- 三阶段提交(3PC)
- 补偿事务(TCC)
- 本地消息表
- 消息事务
- 最大努力通知
- Sagas事务模型
XA事务/两阶段提交
是MySQL分布式事务的实现方式。它主要有三个组件组成:
- **事务管理器(Transaction Manager, TM)**:负责协调分布式事务
- **资源管理器(Resource Manager, RM)**:负责管理本地资源(如 MySQL 数据库)。
- XA 事务 ID(XID):唯一标识一个分布式事务。
适用于简单的,事务量较小的系统
实现
在 MySQL 中,XA 事务通过以下 SQL 语句实现:
XA START
:开始一个 XA 事务。XA END
:结束一个 XA 事务。XA PREPARE
:准备提交事务。XA COMMIT
:提交事务。XA ROLLBACK
:回滚事务。XA RECOVER
:查看处于准备状态的 XA 事务。
原理
XA事务,遵循2PC协议主要有两个工作阶段:
- 准备阶段(Prepare Phase):
- 事务管理器向所有资源管理器发送准备请求。
- 资源管理器执行本地事务操作,并将结果写入日志,但不提交。
- 资源管理器向事务管理器反馈是否可以提交。
- 提交阶段(Commit Phase)
- 如果所有资源管理器都准备好,事务管理器发送提交请求。
- 资源管理器提交本地事务并释放资源。
- 如果任何一个资源管理器未准备好,事务管理器发送回滚请求。
优缺点
优点:
- 强一致性:确保所有参与者要么全部提交,要么全部回滚。
- 跨数据库支持:可以跨多个 MySQL 实例或存储引擎执行分布式事务。
缺点:
- 性能较低:由于需要多次网络通信和日志写入,XA 事务的性能较低。
- 单点故障:如果协调者崩溃,事务可能无法完成。
- 阻塞问题:在准备阶段,参与者需要锁定资源并等待协调者的指令,可能导致长时间阻塞。
使用场景
- 跨数据库事务:在多个 MySQL 实例之间执行分布式事务。
- 跨存储引擎事务:在 InnoDB 和 MyISAM 等不同存储引擎之间执行事务。
- 微服务架构:在微服务架构中,确保跨服务的分布式事务一致性。
改进
为了解决2PC的缺点,提出了新方案
- 三阶段提交(3PC)
- Paxos或Raft协议
- 消息事务(基于消息的最终一致性)
三阶段提交(3PC)
3PC对比2PC,增加了两个功能,增加预提交阶段阶段和超时机制
适用于对一致性和可用性有一定需求的场景
原理
在准备阶段之后添加了预提交的阶段:
- 预提交阶段(Pre-Commit Phase)
- 如果所有参与者都同意提交,协调者发送 Pre-Commit 请求。
- 参与者进入预提交状态,锁定资源并准备提交。
优缺点
优点:
预提交阶段主要解决了2PC的一下几个痛点
- 减少阻塞时间: 2PC会因为协调者的故障而长时间的阻塞,添加预提交阶段后,参与者可以通过超时机制,自行决定提交或者回滚,减少阻塞时间。
- 提高容错能力: 在预提交阶段,3PC的参与者会锁定资源,及时协调者故障,也可以通过超时机制恢复
缺点:
- 实现更复杂
- 性能开销依旧大
- 极端条件下还是会出现数据不一致
结尾
业务主要是简单的业务,所以我直接使用了XA事务的方式,剩下其他的方式之后可以深入了结。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 ✍️灵檠|博客✍️!
评论