前言
分布式事务是几乎所有分布式微服务系统中, 最棘手也是最重要的一个点了. 在讲解分布式事务前, 先了解下数据库事务的特性; 数据库事务的几个特性: 原子性 (Atomicity ), 一致性( Consistency ), 隔离性或独立性( Isolation) 和持久性(Durabilily), 简称就是 ACID.
CAP 定理
CAP 定理是由加州大学伯克利分校 Eric Brewer 教授提出来的, 他指出 web 服务无法同时满足一下 3 个属性:
一致性(Consistency) : 客户端知道一系列的操作都会同时发生(生效)
可用性(Availability) : 每个操作都必须以可预期的响应结束
分区容错性(Partition tolerance) : 即使出现单个组件无法可用, 操作依然可以完成
具体地讲在分布式系统中, 在任何数据库设计中, 一个 Web 应用至多只能同时支持上面的两个属性. 显然, 任何横向扩展策略都要依赖于数据分区. 因此, 设计人员必须在一致性与可用性之间做出选择.
BASE 理论
在分布式系统中, 我们往往追求的是可用性, 它的重要程序比一致性要高, 那么如何实现高可用性呢? 前人已经给我们提出来了另外一个理论, 就是 BASE 理论, 它是用来对 CAP 定理进行进一步扩充的. BASE 理论指的是:
- Basically Available(基本可用)
- Soft state(软状态)
- Eventually consistent(最终一致性)
BASE 理论是对 CAP 中的一致性和可用性进行一个权衡的结果, 理论的核心思想就是: 我们无法做到强一致, 但每个应用都可以根据自身的业务特点, 采用适当的方式来使系统达到最终一致性(Eventual consistency).
分布式事务 TCC
TCC 其实就是采用的补偿机制, 其核心思想是: 针对每个操作, 都要注册一个与其对应的确认和补偿 (撤销) 操作. 它分为三个阶段:
Try 阶段主要是对业务系统做检测及资源预留
Confirm 阶段主要是对业务系统做确认提交, Try 阶段执行成功并开始执行 Confirm 阶段时, 默认 Confirm 阶段是不会出错的. 即: 只要 Try 成功, Confirm 一定成功.
Cancel 阶段主要是在业务执行错误, 需要回滚的状态下执行的业务取消, 预留资源释放.
举个例子, 假入 Bob 要向 Smith 转账, 思路大概是: 我们有一个本地方法, 里面依次调用
1, 首先在 Try 阶段, 要先调用远程接口把 Smith 和 Bob 的钱给冻结起来.
2, 在 Confirm 阶段, 执行远程调用的转账的操作, 转账成功进行解冻.
3, 如果第 2 步执行成功, 那么转账成功, 如果第二步执行失败, 则调用远程冻结接口对应的解冻方法 (Cancel).
Try 部分完成业务的准备工作, confirm 部分完成业务的提交, cancel 部分完成事务的回滚. 基本原理如下图所示.
事务开始时, 业务应用会向事务协调器注册启动事务. 之后业务应用会调用所有服务的 try 接口, 完成一阶段准备. 之后事务协调器会根据 try 接口返回情况, 决定调用 confirm 接口或者 cancel 接口. 如果接口调用失败, 会进行重试.
TCC 方案让应用自己定义数据库操作的粒度, 使得降低锁冲突, 提高吞吐量成为可能. 当然 TCC 方案也有不足之处, 集中表现在以下两个方面:
对应用的侵入性强. 业务逻辑的每个分支都需要实现 try,confirm,cancel 三个操作, 应用侵入性较强, 改造成本高.
实现难度较大. 需要按照网络状态, 系统故障等不同的失败原因实现不同的回滚策略. 为了满足一致性的要求, confirm 和 cancel 接口必须实现幂等.
来源: http://www.jianshu.com/p/8a60e7a813e5