分布式事务

概述

        随着互联网的快速发展,软件系统由原来的单体应用转变为分布式应用。分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务,例如用户注册送积分事务、创建订单减库存事务,银行转账事务等都是分布式事务。

什么是分布式事务

        大多数场景下,我们的应用都只需要操作单一的数据库,这种情况下的事务称之为本地事务(Local Transaction)。本地事务的ACID特性是数据库直接提供支持。本地事务应用架构如下所示:

        毋庸置疑,本地的事务一般是交给了数据库来完成,很省事,但是一旦整个应用数据库拆分以及服务化(SOA),在这种情况下,完成某一个业务功能可能需要横跨多个服务,操作多个数据库。这就涉及到到了分布式事务,需要操作的资源位于多个资源服务器上,而应用需要保证对于多个资源服务器的数据的操作,要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同资源服务器的数据一致性。

分布式事务典型场景  

        一般来说,分布式事务的场景有如下三种类别:

分布式事务解决方案

        分布式事务用于在分布式系统中保证不同节点之间的数据一致性。分布式事务的实现有很多种,最具有代表性的是由Oracle Tuxedo系统提出的XA分布式事务协议。XA对应的实现方案有两阶段提交(2PC)和三阶段提交(3PC)。当然,还有其他的解决分布式事务的方案,如:TCC协议、MQ事务。

2PC(Two-phase commit protocol)

        二阶段提交是一种强一致性设计,2PC 引入一个事务协调者的角色来协调管理各参与者(也可称之为各本地资源)的提交和回滚,二阶段分别指的是准备(投票)提交两个阶段。

        准备阶段

  • 协调者会给各参与者发送准备命令,告诉这些参与者快赶紧除了提交事务之外啥事都做完并及时反馈
  • 协调者会同步等待所有资源的响应,收到响应后才能进入第二阶段
  • 此阶段的协调者有超时机制:假设因为网络原因没有收到某参与者的响应或某参与者挂了,那么超时后就会判断事务失败,向所有参与者发送回滚命令

        提交阶段

  • 如果准备阶段中所有参与者都返回了成功,那么协调者则向所有参与者发送提交事务命令,然后等待所有事务都提交成功之后,返回事务执行成功
  • 如果准备阶段中有一个参与者返回失败,那么协调者就会向所有参与者发送回滚事务的请求,即分布式事务执行失败

提交阶段失败了怎么办?

        1. 第二阶段执行的是回滚事务操作

        不断重试。直到所有参与者都回滚了,不然那些在第一阶段准备成功的参与者会因为在等待协调者的提交命令而一直阻塞着

        2.第二阶段执行的是提交事务操作

        不断重试。因为有可能一些参与者的事务已经提交成功了,这个时候只有一条路,就是头铁往前冲,不断的重试,直到提交成功,到最后真的不行只能人工介入处理。

协调者故障了怎么办?

  • 发送准备命令之前挂了,还行等于事务还没开始,问题不大
  • 发送准备命令之后挂了,这就不太行了,因为可能有些参与者都已经准备好且处于事务资源锁定的状态了。此时不仅事务执行不下去,还会因为锁定了一些公共资源而阻塞系统其它操作
  • 发送回滚事务命令之前挂了,那么事务也是执行不下去,且在第一阶段那些准备成功参与者都阻塞着
  • 发送回滚事务命令之后挂了,这个还行,至少命令发出去了,很大的概率都会回滚成功,资源都会释放。但是如果出现网络分区问题,某些参与者将因为收不到命令而阻塞着
  • 发送提交事务命令之前挂了,这是最惨的,此时所有资源都阻塞着
  • 发送提交事务命令之后挂了,这个还行,也是至少命令发出去了,很大概率都会提交成功,然后释放资源,但是如果出现网络分区问题某些参与者将因为收不到命令而阻塞着

        所以,有必要保证协调者的高可用,这里可以采用集群+故障选举的方式保证。但是,因为参与者的状态其实都是维护在协调者这边的,所以即使有选举,但是选举出来的新协调者,未必就知道在此之前所有参与者的全部状态信息

2PC的不足

        1.性能问题

        XA协议遵循强一致性。在事务执行过程中,各个节点占用着数据库资源,只有当所有节点准备完毕,事务协调者才会通知提交,参与者提交后释放资源。这样的过程有着非常明显的性能问题。

        2.协调者单点故障问题

        事务协调者是整个2PC的核心,一旦事务协调者节点挂掉,参与者收不到提交或是回滚通知,参与者会一直处于中间状态无法完成事务。

        3.丢失消息导致的不一致问题

        在2PC的第二个阶段,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就导致了节点之间数据的不一致。

3PC(Three-phase commit protocol)

        3PC在2PC的基础上增加了CanCommit阶段,并且引入了超时机制(3PC对于协调者和参与者都设置了超时时间,而2PC只有协调者才拥有超时机制一旦事物参与者迟迟没有接到协调者的commit请求,会自动进行本地commit。这样有效解决了协调者单点故障的问题。但是性能问题和不一致的问题仍然没有根本解决。

        三阶段过程:

  • 准备阶段:CanCommit
    • 此阶段,协调者只是询问参与者的自身状况,比如到底挂没挂?负载重不重?等等
    • 好处避免一开始就锁资源,这样某些资源不可用时所有参与者不会都阻塞
  • 预提交阶段:PreCommit
    此阶段和 2PC 的准备阶段一样
  • 提交阶段:DoCommit
    此阶段和 2PC 一样

TCC

        TCC(Try-Confirm-Cancel)又称补偿事务。其核心思想是:"针对每个操作都要注册一个与其对应的确认和补偿(撤销操作)",该模型要求应用的每个服务提供try、confirm、cancel三个接口它分为三个操作:

        Try阶段:主要是对业务系统做检测及资源预留

        Confirm阶段:确认执行业务操作

        Cancel阶段:取消执行业务操作

        TCC事务的处理流程与2PC两阶段提交类似,不过2PC通常都是在跨库的DB层面,而TCC本质上就是一个应用层面的2PC,需要通过业务逻辑来实现。这种分布式事务的实现方式的优势在于,可以让应用自己定义数据库操作的粒度,使得降低锁冲突、提高吞吐量成为可能

        而不足之处则在于对应用的侵入性非常强业务逻辑的每个分支都需要实现try、confirm、cancel三个操作。此外,其实现难度也比较大,需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。为了满足一致性的要求,confirm和cancel接口还必须实现幂等

        TCC的具体原理图如下:

参考文档:

        分布式理论 - 知乎

        分布式第1篇:CAP定理&BASE理论 - 知乎

        https://blog.csdn.net/weixin_31443757/article/details/113330942

        分布式事务概述_分布式事务教程_田守枝Java技术博客

        分布式事务之深入理解什么是2PC、3PC及TCC协议? - 无敌的码农 - 博客园

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值