分布式事务解决方案 -- TCC 笔记

TCC 一种成熟的分布式事务解决方案,可用于解决跨库操做的数据一致性问题。
TCC 是 Try - Confirm - Cancel 缩写,TCC 事务与传统的数据库事务不一样,它存在于业务层面,由系统业务逻辑(事务管理器),进行事务控制。html

TCC 将原业务服务,拆分为了三个操做。可将这三个操做,对应想象成三个方法,每一个方法里有不一样的业务代码。git

  1. Try:检查预留资源
  2. Confirm:业务执行
  3. Cancel:回撤 Try 里执行的操做

image

Try

在 TCC 中,这是一个初步操做,从业务逻辑上来讲,这只是检查资源(数据是否正确或业务上是否可执行等)的操做,真正执行实际业务更改是在 Confirm 中。也就是说,Try 操做事后,与后续执行的 Confirm 操做一块儿(Try - Confirm),才真正构成一个完整的业务逻辑。但若是 Try 操做出现异常,则会执行 Cancel 操做。(Try - Cancel)。
TCC服务须要保证Try操做成功以后,Confirm操做必定能成功。github

Confirm

是对 Try 操做的一个补充。当 TCC事务管理器 决定 commit 全局事务时,就会逐个执行 Try 操做指定的 Confirm 操做,将 Try 未完成的事项最终完成。sql

Cancel

是对 Try 操做的一个回撤。当 TCC 事务管理器决定 rollback 全局事务时,就会逐个执行 Try 操做指定的 Cancel 操做,将 Try 操做已完成的事项所有撤回。数据库

执行流程图

image

异常处理

TCC 须要注意三种异常处理分别是幂等、空回滚、资源悬挂网络

幂等

问题描述并发

网络数据包重复传输,或者异常事务的补偿执行,会致使 TCC 服务的 Try、Confirm或者Cancel操做被重复执行。分布式

解决思路学习

建立事务控制表,记录事务当前执行的状态,每次执行前都查询该状态。设计

空回滚

问题描述

空回滚指的是 Try 未执行,Cancel 执行。

结合 TCC执行流程图 来讲:

  1. 当业务应用运行至 2 调用 Try 操做 中,服务A Try 操做里的代码发起请求,等待 服务B Try 操做结果
  2. 但 服务B 此时因网络缘由,没法接收 Try 操做被请求调用
  3. 此时,业务系统中的事务协调器发现 服务A 的 Try 操做迟迟未响应,认为操做失败;则会去调用 服务A 的 Cancel 操做,去回撤 Try 操做
  4. 同时也会去调用 服务B 的 Cancel 操做,去回撤 服务B 的 Try 操做。若是此时 服务B 网络正常,则会去执行 Cancel 操做。因而发生了 Try 未执行,Cancel 执行。

解决思路

咱们是容许空回滚的产生的,因此咱们须要在 Cancel 操做中,识别出 Try 操做是否执行。而如何识别呢?
在事务控制表中,每一个服务的 Try 操做是否执行,都应有对应记录。因此可在 Cancel 操做中去读取对应服务的 Try 执行记录,来判断是否执行过 Try 操做,从而判断出本次是否为空回滚,不释听任何资源。

资源悬挂

问题描述

Cancel 比 Try 先执行。

接着空回滚流程来讲:

  1. 当 服务B 执行完 Cancel 操做以后,先前 服务A 发起未抵达 服务B 的请求,被服务B接收
  2. 服务B 执行 Try 操做。因而发生了 Cancel 比 Try 先执行。

但事务协调器已经调用了 服务B 的 Cancel 操做,而且 服务B 也成功执行了 Cancel 操做。此时 服务B 中 Try 操做改变的资源将得不到 Confirm 的确认执行,或者 Cancel 回撤执行。这部分资源称为资源悬挂。

解决思路

在发生空回滚的场景下,事务控制表 记录已发生的 Cancel 控制记录,在调用 Try 时,判断是否存在此记录。

业务数据可见性控制

TCC服务的一阶段Try操做会作资源的预留,在二阶段操做执行以前,若是其余事务须要读取被预留的资源数据,那么处于中间状态的业务数据该如何向用户展现,须要业务在实现时考虑清楚;一般的设计原则是 “宁肯不展现、少展现,也很少展现、错展现”。

业务数据并发访问控制

TCC服务的一阶段Try操做预留资源以后,在二阶段操做执行以前,预留的资源都不会被释放;若是此时其余分布式事务修改这些业务资源,会出现分布式事务的并发问题;
在实现TCC服务时,须要考虑业务数据的并发控制,尽可能将逻辑锁粒度降到最低,以最大限度的提升分布式事务的并发性。

https://houbb.github.io/2018/09/02/sql-distribute-transaction-tcc
http://lingo0.github.io/2018/10/15/TCC-transaction学习/
http://www.javashuo.com/article/p-tqveayzw-bg.html
https://cloud.tencent.com/developer/article/1786144
https://zhuanlan.zhihu.com/p/39575038

相关文章
相关标签/搜索