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