柔性事务和TCC

TCC事务

上一篇介绍了2PC和3PC,其主要是为了解决分布式事务中的数据一致问题。这篇就是来了解另外一种
事务的实现方式TCC以及柔性事务。

什么是柔性事务

柔性事务其实是相对传统的事务而言的。我们对传统事务称呼为刚性事务,重视强一致性。而柔性事务更在意最终一致性。

刚性事务

遵循ACID原则,重视强一致性。

柔性事务

遵循BASE理论,实现“基本可用、最终一致”。

ACID理论

ACID应该是所有开发人员最开始接触的事务原则了。ACID是Atomicity(原子性)、Consistency(一致性)、
Isolation(隔离性)、Durability(持久性)的四个首字母。其

原子性(Atomicity)

整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性(Consistency)

一个事务可以封装状态改变(除非它是一个只读的)。事务必须保证系统始终处于一致的状态,不管在任何给定的时间里,并发事务有多少。

隔离性(Isolation)

在并发环境中,并发的事务是相互隔离的,一个事务的执行不能被其他事务干扰。
也就是说,不同的事务并发操纵相同的数据时,每个事务都有各自完整的数据空间,即一个事务内部的操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(Durability)

在事务完成以后,该事务对数据所作的更改便持久的保存,并不会被回滚。

BASE理论

BASE是Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)三个短语的缩写。

Basically Available(基本可用)

基本可用指的是分布式系统在出现未知故障的时候,允许损失部分可用性来。可能是响应时间上的损失,也可能是停止部分服务。

软状态

允许系统中的数据存在中间状态,并认为该中间状态不影响系统可用性。

最终一致性

和之前硬事务的强一致性不同,此处允许系统中各个备份数据在某一时间内存在不一致的情况,但是在一段时间数据同步之后,最终需要能够达到一个一致的状态。

最终一致性
名称描述
因果一致性当一项业务存在顺序操作,后一项操作基于前一项的数据的时候,必须保证后一项操作的时候获得之前项的数据为最新数据,但是和此业务无关的查询则不存在限制。简单的说就是A在B操作之前,那么进行B操作的时候需要保证获得的A数据为最新,而与他们毫无相关的C则不受此影响
读己之所写进程A更新数据后,假如这个值是最新值,那么它应该总是可以访问到的。(它不应该访问到其他副本的旧值)
会话一致性类似上述的会话版本,某次会话时对数据的更新,此会话期间进行更新的新值,会话应该总能访问到
单调读一致性如果进程已经看到过数据对象的某个值,那么任何后续访问都不会返回在那个值之前的值
单调写一致性一个系统需要能够保证来自同一个进程的写操作被顺序地执行。

什么是TCC

TCC方案是可能是目前最火的一种柔性事务方案了。关于TCC(Try-Confirm-Cancel)的概念,最早是由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。在该论文中,TCC还是以Tentative-Confirmation-Cancellation命名。正式以Try-Confirm-Cancel作为名称的是Atomikos公司,其注册了TCC商标。国内最早关于TCC的报道,应该是InfoQ上对阿里程立博士的一篇采访。经过程博士的这一次传道之后,TCC在国内逐渐被大家广为了解并接受。

根据名称我们可以知道TCC存在三个操作。try,confirm,cancel。这三个操作被分为了两个阶段分别对应:阶段一(try0),阶段二(confirm/cancel)

TCC原理

TCC被分为两个阶段,简单的说在try阶段完成业务检查同时完成资源的锁定。在confirm/cancel阶段根据第一阶段的结果进行判断是进行提交还是取消

try-尝试阶段

其主要操作有两部分

  1. 完成业务业务检查。
  2. 为事务预留足够的资源。

confirm-提交阶段

当try完成资源锁定后在confirm阶段进行业务执行。在保证事务幂等性的前提下,对预留的业务资源进行业务操作

cancel-取消

当try节点在进行业务检查或者资源锁定的时候出现异常,则进入此阶段。在保证事务幂等的前提下,对预留资源进行取消或者回滚操作。

try成功
try失败
try-检查业务执行锁定资源
try结果
confirm-使用预留的资源执行提交操作
cancel-取消任务,释放预留资源

例子

上面的介绍描述了TCC每个阶段的任务,但是没有一个具体的例子结合会让人觉得困惑。下面我就简单举个转账的例子来简单的描述下TCC逻辑

场景

现在存在三个账户 张三、李四、王五。现在张三要向李四转账10块,李四需要向王五转账10块。最终的结果应该是张三少了10元、王五多了10元。我们将此作为一个事务。

try阶段

  1. 在尝试业务阶段,首先我们需要检测执行业务的资源是否足够。上面的例子中,首先需要检测张三账户上是否足够。
  2. 检测完业务可以执行后,传统的方式我们需要直接将张三账户金额扣除10块。但是在TCC中,try阶段需要将资源设置在一个扣除和未扣除的中间态。比如用户账户数据中专门设置一个锁定金额。此时我们将张三账户中锁定10元;李四账户中锁定10元,预添加10元;王五账户中预添加十元。

confirm阶段

当try阶段完成所有的资源锁定后,可以进入confirm阶段,在此阶段事务管理器根据之前事务号找到需要执行的事务,并依次发出执行事务的请求。事务开始执行。

cancel阶段

当try阶段,进行业务检查没有通过,或是资源锁定失败的情况。在此阶段事务管理器根据之前事务号找到需要执行的事务,并根据当时事务状态取消各个业务操作。

出现异常

在TCC模式下,出现异常主要是使用日志或者队列进行重试,来保证最终一致性。假如try阶段出现异常,则会触发cancel操作。而cancel操作执行的时候发生异常,系统会使用日志或者队列中是事务信息重试cancel操作。直到事务被成功取消。假如是confirm阶段则是根据事务状态来进行重试,老保证事务完成。当然一般来说我们会有个重试次数的限制,当重试超过限制会对错误信息进行保存,后续由人工进行干涉。

TCC的优点和缺点

TCC的优点是,相比二阶段提交对资源的占用相对较少。在2PC中,在整个事务中都在对资源进行占用。这会导致性能下降。

TCC的缺点也很明显,TCC将部分事务逻辑提到业务层面。需要在业务上对资源进行变更。对于业务方面侵入性比较高,传统业务只需要一个修改接口,但使用TCC模式需要设置try、confirm、cancel三个接口。尤其对于老旧项目会有比较大的改造成本。

使用开源的TCC框架

明白了TCC的有能力的开发或公司可以搭建自己的TCC框架,但是一个稳定可靠的TCC框架需要很高的成本。所以也可以选择开源的TCC框架,比如tcc-transaction

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大·风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值