1.什么是分布式事务?
-
什么是分布式事务
-
分布式系统中涉及到多个数据库或多个应用程序之间的事务处理,在分布式事务中,需要确保所有参与者的事务操作都能够保持一致性,即所有参与者的事务要么全部提交成功,要么全部回滚。
-
-
方案
-
XA协议、TCC事务、最大努力通知等
-
2.XA协议
-
定义
-
XA 就是 X/Open DTP 定义的交易中间件与数据库之间的接口规范(即接口函数
-
-
具体实现
-
2PC(2阶段提交)
-
算法思路
-
参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是回滚操作
-
- 所谓的两个阶段是指
-
第一阶段:准备阶段(投票阶段)
-
协调者向所有参与者发送准备请求
-
参与者执行事务并将结果写入日志,但不提交,随后反馈给协调者(准备就绪或准备失败)。
-
-
第二阶段:提交阶段(执行阶段)
-
如果所有参与者都反馈准备就绪,协调者向所有参与者发送提交请求。
-
参与者收到提交请求后,正式提交事务。
-
如果有任何参与者反馈准备失败,协调者向所有参与者发送回滚请求。
-
参与者收到回滚请求后,回滚事务。
-
-
-
存在的问题
-
数据不一致
-
第二阶段协调者和参与者挂了,挂了的这个参与者在挂之前已经执行了操作。但是由于他挂了,没有人知道他执行了什么操作。这种情况可能导致数据不一致
-
-
同步阻塞
-
执行过程中,所有参与节点都是事务阻塞型的
-
当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态
-
-
单点故障
-
一旦协调者发生故障。参与者会一直阻塞下去。
-
如在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)
-
-
-
-
3PC(3阶段提交)
-
所谓的三个阶段是指
-
在第一阶段,只是询问所有参与者是否可以执行事务操作,并不在本阶段执行事务操作
-
当协调者收到所有的参与者都返回YES时,在第二阶段才执行事务操作(Prepare-Commit)
-
然后在第三阶段在执行commit或者rollback。(Commit)
-
-
如何解决协调者和参与者同时挂掉的问题
-
2PC在提交阶段发生故障,其他参与者可能无法确定是该提交还是回滚 ,但在3PC中如果发现有参与者的状态是“Prepare-Commit”或“Commit”,新的协调者可以根据这些状态决定执行提交操作,因为预提交状态意味着所有参与者已经准备好提交了。
-
-
-
3.TCC
-
什么是TCC
-
将整个分布式事务分解为若干个子事务,每个子事务都有一个try、confirm和cancel三个操作,通过这些操作来实现分布式事务的执行和回滚
-
Try:在try阶段,参与者尝试执行本地事务,并对全局事务预留资源。如果try阶段执行成功,参与者会返回一个成功标识,否则会返回一个失败标识。
-
Confirm:如果所有参与者的try阶段都执行成功,则协调者通知所有参与者提交事务,那么就要执行confirm阶段,这时候参与者将在本地提交事务,并释放全局事务的资源。
-
Cancel:如果任何一个参与者在try阶段执行失败,则协调者通知所有参与者回滚事务。那么就要执行cancel阶段。
-
-
-
TCC存在问题及解决:
-
存在悬挂事务问题
-
对于已经空回滚的业务,如果以后继续执行try,就永远不可能confirm或cancel,这就是业务悬挂
-
解决:引入分布式事务记录表,根据事务id查询是否有记录,如果当前存在,并且记录的状态是cancel,则拒绝本次try请求。
-
-
空回滚问题
-
在未执行try操作时先执行了cancel操作,这时cancel不能做回滚,就是空回滚。
-
解决:引入分布式事务记录表,事务id查询是否有try的记录,如果没有,则进行一次空回滚即可
-
-
4.最大努力通知
-
基于MQ来实现分布式事务分为两种:
-
可靠消息最终一致性
-
保证消息可靠的方法本地消息表 和事务消息
-
-
最大努力通知
-
最大努力通知无法保证每个接收者都能成功接收到消息,但是可以尽最大努力去通知。
-
-