转 分布式事务的四种解决方案

例如在下单场景下,库存和订单若是不在同一个节点上,就涉及分布式事务。html

解决方案

在分布式系统中,要实现分布式事务,无外乎那几种解决方案。程序员

1、两阶段提交(2PC)

两阶段提交(Two-phase Commit,2PC),经过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务。数据库

1. 运行过程

1.1 准备阶段

协调者询问参与者事务是否执行成功,参与者发回事务执行结果。网络

1.2 提交阶段

若是事务在每一个参与者上都执行成功,事务协调者发送通知让参与者提交事务;不然,协调者发送通知让参与者回滚事务。异步

须要注意的是,在准备阶段,参与者执行了事务,可是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。分布式

2. 存在的问题

2.1 同步阻塞 全部事务参与者在等待其它参与者响应的时候都处于同步阻塞状态,没法进行其它操做。ui

2.2 单点问题 协调者在 2PC 中起到很是大的做用,发生故障将会形成很大影响。特别是在阶段二发生故障,全部参与者会一直等待状态,没法完成其它操做。spa

2.3 数据不一致 在阶段二,若是协调者只发送了部分 Commit 消息,此时网络发生异常,那么只有部分参与者接收到 Commit 消息,也就是说只有部分参与者提交了事务,使得系统数据不一致。htm

2.4 太过保守 任意一个节点失败就会致使整个事务失败,没有完善的容错机制。中间件

2、补偿事务(TCC)

TCC 其实就是采用的补偿机制,其核心思想是:针对每一个操做,都要注册一个与其对应的确认和补偿(撤销)操做。它分为三个阶段:

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

  • Confirm 阶段主要是对业务系统作确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm必定成功。

  • Cancel 阶段主要是在业务执行错误,须要回滚的状态下执行的业务取消,预留资源释放。

举个例子,假入 Bob 要向 Smith 转帐,思路大概是: 咱们有一个本地方法,里面依次调用

  1. 首先在 Try 阶段,要先调用远程接口把 Smith 和 Bob 的钱给冻结起来。
  2. 在 Confirm 阶段,执行远程调用的转帐的操做,转帐成功进行解冻。
  3. 若是第2步执行成功,那么转帐成功,若是第二步执行失败,则调用远程冻结接口对应的解冻方法 (Cancel)。

优势: 跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些

缺点: 缺点仍是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,因此须要程序员在实现的时候多写不少补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。

3、本地消息表(异步确保)

本地消息表与业务数据表处于同一个数据库中,这样就能利用本地事务来保证在对这两个表的操做知足事务特性,而且使用了消息队列来保证最终一致性。

  1. 在分布式事务操做的一方完成写业务数据的操做以后向本地消息表发送一个消息,本地事务能保证这个消息必定会被写入本地消息表中。
  2. 以后将本地消息表中的消息转发到 Kafka 等消息队列中,若是转发成功则将消息从本地消息表中删除,不然继续从新转发。
  3. 在分布式事务操做的另外一方从消息队列中读取一个消息,并执行消息中的操做。

优势: 一种很是经典的实现,避免了分布式事务,实现了最终一致性。

缺点: 消息表会耦合到业务系统中,若是没有封装好的解决方案,会有不少杂活须要处理。

4、MQ 事务消息

有一些第三方的MQ是支持事务消息的,好比RocketMQ,他们支持事务消息的方式也是相似于采用的二阶段提交,可是市面上一些主流的MQ都是不支持事务消息的,好比 RabbitMQ 和 Kafka 都不支持。

以阿里的 RocketMQ 中间件为例,其思路大体为:

第一阶段Prepared消息,会拿到消息的地址。 第二阶段执行本地事务,第三阶段经过第一阶段拿到的地址去访问消息,并修改状态。

也就是说在业务方法内要想消息队列提交两次请求,一次发送消息和一次确认消息。若是确认消息发送失败了RocketMQ会按期扫描消息集群中的事务消息,这时候发现了Prepared消息,它会向消息发送者确认,因此生产方须要实现一个check接口,RocketMQ会根据发送端设置的策略来决定是回滚仍是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。

优势: 实现了最终一致性,不须要依赖本地数据库事务。

缺点: 实现难度大,主流MQ不支持,RocketMQ事务消息部分代码也未开源。

总结

经过本文咱们总结并对比了几种分布式分解方案的优缺点,分布式事务自己是一个技术难题,是没有一种完美的方案应对全部场景的,具体仍是要根据业务场景去抉择吧。阿里RocketMQ去实现的分布式事务,如今也有除了不少分布式事务的协调器,好比LCN等,你们能够多去尝试。

相关文章
相关标签/搜索