常见的三种分布式事务

98 阅读3分钟

分布式事务用于给分布式应用提供原子性、一致性、隔离性、持久性这四大事务特性以满足现实需求。比如一个支付系统,如果首先进行优惠券的扣减,然后进行扣款。如果扣款失败,那么优惠券的扣减就需要回滚。

分布式的异常是可以传递的,但是实现处理异常的回滚操作则需要复杂的编程,而且编程实现的回滚操作依旧存在异常的可能。这就需要分布式事务的支持,在事务提交之前,任何操作的回滚都可以是无条件的。

分布式事务是一个非常损耗性能的技术,如果你的事务链路非常复杂且耗时比较多,那么请通过巧妙的设计避免分布式事务,或者是进行事务的异步化。

现在先介绍几种分布式事务的实现方式,后面将会介绍如何设计减少分布式事务影响的用户体验。

2PC

即二阶段提交,是一种强一致性设计。引入了事务协调者来协调各个独立事务的提交与回滚。 这里的二阶段指的是准备与提交两个阶段。

  1. 当一个独立事务完成了他所有操作之后,就从准备状态进入了提交状态。
  2. 当中间链路中任意一个独立事务出现异常,则会触发提交状态的所有事务执行回滚操作。
  3. 当所有独立事务都进入了提交阶段后,所有事务提交成功即整个事务完成。
  4. 但不管是回滚还是提交都是存在失败的,这个时候只能进行不断重试或者人工介入。

2PC 是一个同步阻塞协议,阻塞等待直至得到协调者响应之后才可以进入下一个阶段。

而协调者是一个单点中心,也存在故障的情况。即使可以通过选举等方式避免整个事务的阻塞,但是在极端条件下,会存在数据不一致的问题。

3PC

3PC 是为了解决 2PC 的一些问题的,3PC 为参与者引入了超时机制,以至参与者可以通过一个新的状态同步各自的状态。这个状态就是预提交状态。

当一个独立事务主观上可用且可靠,那么就会进入预提交阶段。

这个阶段主要是为了提供给协调者一个状态,解决协调者和某个参与者同时挂掉之后,新协调者不知道当前该提交还是回滚的问题,减少了新协调者的决策成本,但无法根本解决问题。

TCC 补偿性事务

TCC 有三个阶段,即 Try 预留,Confirm 确认,Cancel 撤销。

TCC 不存在资源阻塞的问题,每个方法直接执行事务提交,如果出现异常才通过 Cancel 进行回滚补偿,这就是补偿性事务。

但每个阶段的功能需要进行自定义,对业务侵入性强,且功能代码不一定可以进行复用。