项目
博客
文档
归档
资源链接
关于我
项目
博客
文档
归档
资源链接
关于我
27| 分布式事务
2024-08-13
·
·
原创
·
·
本文共 558个字,预计阅读需要 2分钟。
事务:指的就是一个操作单元,在这个操作单元中的所有操作最终要保持一致的行为,要么所有操作都成功,要么所有的操作都被撤销 一个是`本地事务`:本地事物其实可以认为是数据库提供的事务机 一个是`分布式事务`: 指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于`不同的分布式系统`的不同节点之上。简单的说,就是`一次大的操作由不同的小操作组成`,这些小的操作分布在不同的服务器上,且属于不同的应用分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性 产生的原因 * `业务发展,数据库的拆分-分库分表` * `SOA和微服务架构的使用` * `多个微服务之间调用异常` * `网络异常、请求超时、数据库异常、程序宕机`等 Base理论: CAP 中的一致性和可用性进行一个权衡的结果,核心思想就是:我们`无法做到强一致`,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到`最终一致性`, 来自 ebay 的架构师提出。 - `Basically Available(基本可用)`: 假设系统,出现了不可预知的故障,但还是能用, 可能会有性能或者功能上的影响,比如RT是10ms,变成50ms - `Soft state(软状态`): 允许系统中的数据存在`中间状态`,并认为该状态不影响系统的整体可用性,即允许系统在多个`不同节点的数据副本存在数据延时` - `Eventually consistent(最终一致性`): 系统能够保证在没有其他新的更新操作的情况下,数据`最终`一定能够`达到一致`的状态,因此所有客户端对系统的数据访问最终都能够获取到最新的值。 数据一致性 * 强一致:操作后的能立马一致且可以访问 * 弱一致:`容忍部分或者全部访问不到` * 最终一致:弱一致性经过多一段时间后,都一致且正常 常见分布式事务解决方案 * `2PC 和 3PC`:两阶段提交, 基于XA协议 * `TCC` :Try、Confirm、Cancel * `事务消息:最大努力通知型 分布式事务分类 * 刚性事务:遵循ACID * 柔性事务:遵循BASE理论 分布式事务框架 * TX-LCN:支持2PC、TCC等多种模式。https://github.com/codingapi/tx-lcn。更新慢(个人感觉处于停滞状态) * Seata:支持 AT、TCC、SAGA 和 XA 多种模式。https://github.com/seata/seata。背靠阿里,专门团队推广,阿里云商业化产品GTS。https://www.aliyun.com/aliware/txc * RocketMq:自带事务消息解决分布式事务。https://github.com/apache/rocketmq #### 事务核心概念 `X/OpenDTP 事务模型`:是`X/Open` 这个组织定义的一套分布式事务的标准,也就是定义了规范和 API 接口,由各个厂商进行具体的实现。`DTP` 是分布式事物处理(Distributed Transaction Processing)的简称 `XA协议`: `XA`是由X/Open组织提出的分布式事务规范。XA规范主要定义了(全局)`事务管理器`(TM)和(局部)`资源管理器`(RM)之间的接口。主流的数据库产品都实现了XA接口,是一个双向的系统接口,在事务管理器以及多个资源管理器之间作为通信桥梁。 `JTA`:`Java Transaction API`,java根据XA规范提供的事务处理标准 `AP`: application, 应用程序也就是业务层,微服务等。 `RM`: `Resource Manager`,资源管理器。一般是数据库,也可以是其他资源管理器,比如消息队列,文件系统 `TM`: `Transaction Manager` ,事务管理器、事务协调者,负责接收来自用户程序(AP)发起的 XA 事务指令,并调度和协调参与事务的所有 RM(数据库),确保事务正确完成 `事务模型`: 在分布式系统中,每一个机器节点能够明确知道自己在进行事务操作过程中的 结果是成功还是失败,但无法直接获取到其他分布式节点的操作结果。当一个事务操作跨越多个分布式节点的时候,为了保持事务处理的 ACID 特性,需要引入一个“协调者”(TM)来统一调度所有分布式节点的执行逻辑,这些被调度的分布式节点被称为 AP。TM 负责调度 AP 的行为,并最终决定这些 AP 是否要把事务真正进行提交到(RM) #### XA两阶段提交2PC流程解析 XA协议规范-实现分布式事务的原理如下 * 一般习惯称为 两阶段提交协议(The two-phase commit protocol,2PC) * 是XA用于在全局事务中协调多个资源的机制,MySql5.5以上开始支持 * 准备阶段:事务管理器给每个参与者都发送Prepared消息,每个数据库参与者在本地执行事务,并写本地的`Undo/Redo`日志,此时事务`没有提交`。 * Undo日志是记录修改前的数据,用于数据库回滚 * Redo日志是记录修改后的数据,用于提交事务后写入数据 * 提交阶段: * 如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚(Rollback)消息,否则发送提交(Commit)消息; * 参与者根据事务管理器的指令执行【提交】或者【回滚】操作,并释放事务处理过程中使用的锁资源 * 注意:必须在最后阶段释放锁资源。 总结 * XA协议简单,数据库支持XA协议,开发使用成本比较低 * 对业务侵⼊很小,最⼤的优势就是对使⽤⽅透明 * 用户可以像使⽤本地事务⼀样使⽤基于 XA 协议的分布式事务,能够严格保障事务 ACID 特性 * 事务执⾏过程中需要将所需资源全部锁定,也就是俗称的刚性事务 * 刚性事务:遵循ACID * 柔性事务:遵循BASE理论 * 性能不理想,占用锁资源比较多,高并发常见下无法满足 * 商业付费数据库支持好,mysql目前支持不是很完善 * 基于 XA 协议的 除了2PC,还有 3PC等 * 三段提交(3PC)是二阶段提交(2PC)的一种改进版本 ,为解决两阶段提交协议的阻塞问题 * 采用`超时机制`,解决TM故障后RM的阻塞问题,但与此同时却多了一次网络通信,性能上也不理想 * 2PC和3PC目前使用不是很多,只做简单了解即可 #### TCC柔性事务的解决方案 什么是TCC柔性事务 * 刚性事务:遵循ACID * 柔性事务:遵循BASE理论 * TCC: * 将事务提交分为 * Try:完成所有业务检查( 一致性 ) ,预留必须业务资源( 准隔离性 ) * Confirm :对业务系统做确认提交,默认 Confirm阶段不会出错的 即只要Try成功,Confirm一定成功 * Cancel : 业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放, 进行补偿性 * TCC 事务和 2PC 的类似,Try为第一阶段,Confirm - Cancel为第二阶段,它对事务的提交/回滚是通过执行一段 confirm/cancel 业务逻辑来实现,并且也并没有全局事务来把控整个事务逻辑 | 含义 | 操作方法 | | ------------------------------------------------------------ | -------- | | 预留业务资源/数据效验 | Try | | 确认执行业务操作,提交数据,不做任何业务检查,try成功,confirm必定成功,需保证幂等 | Confirm | | 取消执行业务操作,回滚数据,需保证幂等,也是常说的补偿性事务 | Cancel | * 优点: * 它把事务运行过程分成 Try、Confirm/Cancel 两个阶段 * 每个阶段由业务代码控制,这样事务的锁力度可以完全自由控制 * 不存在资源阻塞的问题,每个方法都直接进行事务的提交 * 缺点 * 在业务层编写代码实现的两阶段提交,原本一个方法,现在却需要三个方法来支持 * 对业务的侵入性很强,不能很好的复用 * 注意:使用TCC时要注意Try - Confirm - Cancel 3个操作的**幂等控制**,由于网络原因或者重试操作都有可能导致这几个操作的重复执行 #### 事务消息 事务消息: 消息队列提供类似Open XA的分布式事务功能,通过消息队列事务消息能达到分布式事务的最终一致 半事务消息: 暂不能投递的消息,发送方已经成功地将消息发送到了消息队列服务端,但是服务端未收到生产者对该消息的二次确认,此时该消息被标记成“暂不能投递”状态,处于该种状态下的消息即半事务消息。 消息回查: 由于网络闪断、生产者应用重启等原因,导致某条事务消息的二次确认丢失,消息队列服务端通过扫描发现某条消息长期处于“半事务消息”时,需要主动向消息生产者询问该消息的最终状态(Commit或是Rollback),该询问过程即消息回查。 目前较为主流的MQ,比如ActiveMQ、RabbitMQ、Kafka、RocketMQ等,只有RocketMQ支持事务消息 * 如果其他队列需要事务消息,可以开发个消息服务,自行实现半消息和回查功能 好处 * 事务消息不仅可以实现应用之间的解耦,又能保证数据的最终一致性 * 同时将传统的大事务可以被拆分为小事务,能提升效率 * 不会因为某一个关联应用的不可用导致整体回滚,从而最大限度保证核心系统的可用性 缺点 * 不能实时保证数据一致性 * 极端情况下需要人工补偿,比如 假如生产者成功处理本地业务,消费者始终消费不成功 #### 第三方支付平台和微服务之间的交互 * 支付业务 * 支付宝支付 * 微信支付 * 其他支付 * 多个服务之间通信,怎么保证分布式事务呢? * 利用最终一致性思想,也叫柔性事务解决方案 ![](https://yn-blog.oss-cn-chengdu.aliyuncs.com/v_2024/2024-07-20/wechatpay.png)