在我的博客中, 介绍过很多关于分布式和事务的文章, 在阅读本文之前, 希望读者可以对这些基础知识有所了解, 这里简单把之前的文章列举下, 已经按照顺序排好, 可按顺序阅读.
初识分布式系统
关于分布式一致性的探究
分布式系统的 CAP 理论(需要到博客中查看)
分布式系统的 BASE 理论(需要到博客中查看)
Java 中的事务 --JDBC 事务和 JTA 事务
Java 中的事务 -- 全局事务与本地事务
关于分布式事务, 两阶段提交协议, 三阶提交协议
深入理解分布式系统的 2PC 和 3PC
这里简单总结下以前几篇文章, 算是本文的背景知识. 在分布式系统中, 存在 CAP 理论, 即可用性, 数据一致性和分区容错性无法同时满足. 所以, 一个基于 CAP 的最终一致性理论 BASE 理论是目前解决分布式问题比较靠谱的.
在分布式系统中, 是无法使用本地事务保证数据的一致性的. 一种标准的分布式事务就是全局事务(DTP 模型). 他是基于 2PC 来控制的. 但是由于 2PC 自身就存在同步阻塞的问题, 这也就导致全局事务效率很低. 所以, 这种全局事务并不适合解决大型网站的分布式事务问题.
柔性事务
在业内, 主要用来解决分布式事务的方案是使用柔性事务. 所谓柔性事务, 相比较与数据库事务中的 ACID 这种刚性事务来说, 柔性事务保证的是 "基本可用, 最终一致." 这其实就是基于 BASE 理论, 保证数据的最终一致性.
虽然柔性事务并不像刚性事务那样完全遵循 ACID, 但是, 也是部分遵循 ACID 的, 简单看一下关于 ACID 四个属性, 柔性事务的支撑程度:
柔性事务的基础
前面介绍过了柔性事务的定义, 目前, 在业内, 关于柔性事务, 最主要的有以下三种类型: 异步确保型, 补偿型, 最大努力通知型.
这三种类型的柔性事务基本都有对应的实现, 不同的场景需要使用不同的柔性事务类型. 而这几种柔性事务类型, 其实还是依赖一些基础模式的, 或者叫做基础接口, 基础功能.
比如, 要想使用可靠消息最终一致来实现异步确保型柔性事务, 就依赖接幂等操作和可查询操作. 关于具体实现, 我们在后面的文章中介绍, 本文简单介绍下这些实现柔性事务依赖的基础模式.
注意, 下面要介绍的柔性事务的模式, 并不是柔性事务的方案. 这些是做柔性事务的基础. 也就是说, 如果你想做柔性事务, 你的接口和功能要满足下面的几个要求. 不一定要都满足, 因为不同的方案的要求不一样. 但是都不满足的话, 是不可能做柔性事务的.
可查询操作
可查询操作, 几乎是所有的分布式解决方案都需要的.
举一个常见的分布式场景的例子, 如订单处理这一功能:
以上这个支付订单处理的例子中, 除了订单服务本地更新订单状态以外的所有操作, 都需要调用 RPC 接口来执行, 这种情况单纯的本地事务就无法保证数据的一致性了. 就需要引入分布式事务. 在分布式事务执行过程中, 如果某一个步骤执行出错, 就需要明确的知道其他几个操作的处理情况, 这就需要其他的服务都能够提供查询接口, 保证可以通过查询来判断操作的处理情况.
为了保证操作的可查询, 需要对于每一个服务的每一次调用都有一个全局唯一的标识, 可以是业务单据号(如订单号), 也可以是系统分配的操作流水号(如支付记录流水号). 除此之外, 操作的时间信息也要有完整的记录.
幂等操作
幂等性, 其实是一个数学概念. 幂等函数, 或幂等方法, 是指可以使用相同参数重复执行, 并能获得相同结果的函数, 如:
f(f(x)) = f(x)
在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同. 也就是说, 同一个方法, 使用同样的参数, 调用多次产生的业务结果与调用一次产生的业务结果相同.
这一个要求其实也比较好理解, 因为要保证数据的最终一致性, 很多解决防范都会有很多重试的操作, 如果一个方法不保证幂等, 那么将无法被重试.
幂等操作的实现方式有多种, 如在系统中缓存所有的请求与处理结果, 检测到重复操作后, 直接返回上一次的处理结果等.
可补偿操作
提到事务, 为了保证原子性, 就可能发生 commit 和 rollback, 那么在分布式事务中, 要想进行 rollback, 就需要提供可补偿操作.
比如上面的订单处理的例子中, 在调用积分服务给积分帐户增加积分操作执行之后, 经过分布式事务协调, 最终决定回滚整个事务, 那么就需要提供一个调用积分服务给积分帐户扣减积分的操作.
并且, 补偿操作同时也需要满足幂等性.
TCC 操作
TCC 即 Try-Confirm-Cancel.
Try: 尝试执行业务
完成所有业务检查(一致性) 预留必须业务资源(准隔离性)
Confirm: 确认执行业务
真正执行业务 不作任何业务检查 只使用 Try 阶段预留的业务资源 Confirm 操作要满足幂等性
Cancel: 取消执行业务
释放 Try 阶段预留的业务资源
Cancel 操作要满足幂等性
这种类型和可补偿操作类似, 就是提供一种提交和回滚的机制. 是一种典型的两阶段类型的操作. 这里说的两阶段类型操作并不是指 2PC, 他和 2PC 还是有区别的.
TCC 与 2PC 协议比较
TCC 位于业务服务层而非资源层
TCC 没有单独的准备 (Prepare) 阶段, Try 操作兼备资源操作与准备能力 Try 操作可以灵活选择业务资源的锁定粒度(以业务定粒度)
TCC 有较高开发成本
总结
本文主要是简单介绍了一下柔性事务和柔性事务实现的基础. 柔性事务是目前主流的分布式事务解决方案, 其基础模式包含四个: 幂等操作, 可补偿操作, 可查询操作和 TCC 操作. 后续文章会分别介绍关于分布式事务的解决方案, 敬请期待.
来源: http://blog.51cto.com/13732225/2145564