-
目录
-
前言
-
一阶段提交(1PC)
-
两阶段提交(2PC)
-
三阶段提交(3PC)
-
TCC
-
SAGA
-
本地消息表
-
最大努力补偿
-
总结
前言
分布式的 CAP 理论应该是人尽皆知了,它描述了一致性(C)、可用性(A)、分区容错性(P)的一系列权衡。
很多时候,我们要在一致性和可用性之间权衡,而分布式事务,就是在这个大的前提下,尽可能的达成一致性的要求。
目标很小,问题很大,做法也各有不同。
**“如何在微服务中实现分布式事务?”**一般在被问到这样的问题时,我都会回答“要尽量避免使用分布式事务”,这也是 Martin Fowler 所推荐的。
但现实总是残酷的,拆分了微服务之后,分布式事务是非常硬核的需求,是绕不开的,我们依然要想办法搞定它。
但分布式环境错综复杂,还伴随着网络状况产生的超时,如何让事务达到一致性的状态,难度很大。
分布式事务,由一系列小的子事务组成。这些子事务,同大的分布式事务一样,同样要遵循 ACID 的原则。
在一致性这个属性上,根据达到一致性之前所存在的时间,又分为强一致性和最终一致性(BASE)。
注意,对于子事务,这里有个小小的误解。并不是只有和数据库打交道的操作,才叫做事务。
在微服务环境下,如果你通过 RPC 调用了另外一个远程接口,并造成了相关数据状态的变化,这个 RPC 接口,也叫做事务。
所以,在分布式事务中,我们把这些子事务涉及到的操作,叫做资源。当操作能正常完成的时候,根本不需要什么额外处理。事务主要处理的是发生异常之后的流程。
下面,我们就来看一下常见的分布式事务解决方案。
先来看一下最简单的事务提交情况。
如果你的业务,只有一个资源需要协调,那么它可以直接提交。比如,你使用了一个数据库,那么就可以直接使用 begin,commit 等指令完成事务提交。
在 Spring 中,通过注解,就可以完成这样的事务。如果发生了嵌套事务,它的实现方式,本质上,是通过 ThreadLocal 向下传递的。所以如果你的应用中有子线程相关的事务需要管理,它办不到。
我们再来看分布式事务。所谓的分布式事务,就是协调 2 个或者多个资源,达到共同提交或者共同失败的效果,也就是分布式的 ACID。
在一阶段提交的概念扩展下,最简单的分布式事务解决方案,就是二阶段提交。二阶段提交不是指有两个参与资源,而是说有两个分布式的协调阶段,它可能有多个资源需要协调。
| 重要参与者
如下:
协调者(coordinator),也就是我们需要自建事务管理器,通常在整个系统中只有一个
事务参与者(participants),就是指的我们所说的资源,通常情况下会有多个,否则也称不上分布式事务了
| 过程
- 广义上的 2PC(two phase commit),有哪两阶段呢?
- client 分布式事务发起者
- commit-request/voting 准备阶段
- commit/rollback 提交或者回滚

准备阶段,也叫做 voting 阶段。所谓的 voting,就是参与者告知协调者,自己的资源到底是能够提交(代表它准备好了),还是取消本次事务(比如发生异常)。
这个投票比较有意思,只要有一个参与者返回了 false,本次事务就需要终止,然后执行 rollback。只有全票通过,才会正常 commit。协调者将这个结果,周知所有参与者的这个过程,就是二阶段。
二阶段提交其实非常容易理解。你可以把每个参与者的执行,想象成正常的 SQL 更新语句。
它们一直挂在那里等待,直到协调者给出确切的 commit 或者 rollback 消息,才会正常往下执行。
| 问题

5288

被折叠的 条评论
为什么被折叠?



