文件名称:
分布式事务 Seata TCC 模式深度解析
开发工具:
文件大小: 1mb
下载次数: 0
上传时间: 2019-07-01
详细说明:本文档的内容主要分为以下四个部分:
1、Seata TCC 模式的原理解析;
2、从 TCC 的业务模型与并发控制分享如何设计一个 TCC 接口,并且适配 TCC 模型;
3、如何控制异常;
4、性能优化,使得 TCC 模式能够满足更高的业务需求。Seat关注的就是微服务架构下的数据一致性问题,是一整套的分布式事务解决方案。 Seat框架包
含两种模式,一种是AT模式。AT模式主要从数据分片的角度,关注多DB访问的数据一致性,当
然也包括多服务下的多DB数据访问一致性问题。
另外一个就是τCC模式,TCC模式主要关注业务拆分,在按照业务横向扩展资源时,解决微服务问
调用的一致性问题,保证读资源访问的事务属性
今天我们主要讲的就是TCC模式。在讲TCC之前,我们先回顾一下AT模式,这样有助于我们理
解后面的TCC模式
1.2AT模式
对于AT模式,之前其他同学已经分享过很多次,大家也应该比较熟悉」。AT模式下,把每个数据
库被当做是一个 Resource, Seat里称为 Data Source resource。业务通过JDBC标准接口访问数
据库资源时, Seat框架会对所有请求进行拦截,做一些操作。每个本地事务提交时, Seat rm
Resource Manager,资源管理器)都会向TC( Transaction Coordinator,事务协调器)注册
个分支事务。当请求链路调用完成后,发起方通知TC提交或回滚分布式事务,进入二阶段调用流程。
此时,TC会根据之前注册的分支事务回调到对应参与者去执行对应资源的第二阶段。TC是怎么找
到分支事务与资源的对应关系呢?每个资源都有一个全局唯一的资源ID,并且在初始化时用该ID
问TC注册资源。在运行时,每个分攴事务的注册都会带上其资源ID。这样TC就能在二阶段调用
时正确找到对应的资源
这就是我们的AT模式。简单总结一下,就是把每个数据库当做一个 Resource,在本地事务提交时
会去注册一个分支事务。
1.3TCC模式
那么对应到TCC模式里,也是一样的, Seat框架把每组TCC接口当做一个 Resource,称为TCC
Resource。这套TCC接口可以是RPC,也以是服务内M调用。在业务启动时, Seat框架公自
动扫描识别到TCC接口的调用方和发布方。如果是RPC的话,就是sofa: reference、sofa: service、
dubbo: reference、 dubbo: service等。
扫描到TCC接口的调用方和发布方之后。如果是发布方,会在业务启动时向TC注册 TCC Resource,
与 Data source resource一样,每个资源也会带有一个资源ID。
如果是调用方, Seat框架会给调用方加上切面,与AT模式·样,在运行时,该切面会拦截所有对
TCC接口的调用。每调用一次Try接口,切面会先向TC注册一个分支事务,然后才去执行原来的
RPC调用。当请求链路调用完成后,TC通过分支事务的资源ID回调到正确的参与者去执行对
TCC资源的 Confirm或 Cance方法。
在讲完了整个框架模型以后,大家可能会问TCC三个接口怎么实现。因为框架木身很简单,主要是
扫描τC℃接口,注册资源,拦截接口调用,注册分支事务,最后回调二阶段接口。最核心的实际上
是τCC接口的实现逻辑。下面我将根据妈蚁金服内部多年的实践来为人家分析怎么实现一个完备的
TCC接口。
2TCC业务模式与并发控伟
2.1TCC设计原贝
从τCC模型的框架可以发现,TCC模型的核心在于TCC接口的设计。用户在接入TCC时,大部
分工作都集中在如何实现TCC服务上。下面我会分享蚂蚁金服内多年的TCC应用实践以及在TCC
设计和实现过程中的注意事项。
设计一套TCC接口最重要的是什么?主要有两点,第一点,需要将操作分成两阶段完成。TCC(Tr
Canηfirm- Cancel)分布式事务模型相对于ⅩA等传统模型,其特征在于它不依赖RM对分布式事务
的支持,而是通过对业务逻辑的分解来实现分布式事务。
TCC模型认为对于业务系统中一个特定的业务逻辑,其对外提供服务时,必须接受一些不确定性,
即对业务逻辑初步操作的调用仅是一个临时性操作,调用它的主业务服务保留了后续的取消权。如果
主业务服务认为全局事务应该回滚,它会要求取消之前的临时性操作,这就对应从业务服务的取消操
作。而当主业务服务认为全局事务应该提交时,它会放弃之前临时性操作的取消权,这对应从业务服
务的确认操作。每一·个初步操作,最终都会被确认或取消。因此,针对一个具体的业务服务,TCC分
布式事务模型需要业务系统提供三段业务逻辑
1.初步操作Ty:完成所有业务检查,预留必须的业务资源。
2.确认操作 Confirm:真正执行的业务逻辑,不做任何业务检查,只使用Try阶段预留的业务
资源。因此,只要Try操作成功, Confirm必须能成功。另外, Confirm操作需满足幂等性,
保证一笔分布式事务能且只能成功一次。
3.取消操作 Cancel:释放Try阶段预留的业务资源。冋样的, Cancel操作也需要满足幂等性。
第二点,就是要根据自身的业务模型控制并发,这个对应ACID中的隔离性。后面会详细讲到。
2.2账务系统模型设计
下面我们以金融核心链路里的账务服务来分析一下。首先一个最简化的账务模型就是图中所列,每个
用户或商户有一个账户及其可用余额。然后,分析下账务服务的所有业务逻辑操作,无论是交易、充
值、转账、退款等,都可以认为是对账户的加钱与扣钱。
Part2:业务模型与并发控制
TCC设计-业务模型
账务系统
Resource- TCC
Resource-TCC
Try
账务借
Try
账务贷
Confirm)记服务
Confirm
记服务
Cancel
Cancel
SOFA Channel
1039
因此,我们可以把账务系统拆分成两套TCC接口,即两个 TCC Resource,一个是加钱TCC接口,
个是扣钱TCC接口。
那这两套接口分别需要做什么事情呢?如何将其分成两个阶段完成?下面将会举例说明TCC业务
模式的设计过程,并逐渐优化。
我们先来看扣钱的TCC资源怎么实现。场景为A转账30元给B。账户A的余额中有100元,
需要扫除其中30元。这里的余额就是所谓的业务资源,按照前面提到的原则,在第一阶段需要检查
并预留业务资源,因此,我们在扣钱TcC资源的Try接口里先检查A账户余额是否足够,然后预
留余额里的业务资源,即扣除30元
Fart2:业务型与井发控制
TcC设计-业务模型
扣钱场景为:欺户A上有100元,要扣除其中的30元
Try:检查余额,扣除其中30元;
账户A
可用余额
100
Confirm:空提交
账户A:
可用余额
100
Cancel:返还扣除的30元。
账户A:
可用余额
100
SOFA Channel
1139
在 Confirm接口,由于业务资源已经在Try接口里扣除掉∫,那么在第二阶段的 Confirm接口里,
可以什么都不用做。而在 Cancel接凵里,则需要把Try接凵里扣除掉的30元还给账户。这是
个比较简单的扣钱TCC资源的实现,后面会继续优化它。
而在加钱的τcC资源里。在第一阶段Try接口里不能直接给账户加钱,如果这个时候给账户增加了
可用余额,那么在一阶段执行完后,账户里的钱就可以被使用了。但是一阶段执行完以后,有可能是
要回滚的。因此,真正加钱的动作需要放在 Confirm接凵里。对于加钱这个动作,第阶段Try接
口里不需要预留仁何资源,可以设计为空操作。那相应的, Cancel接口没有资源需要释放,也是
个空操作。只有真正需要提交时,再在 Confirm接口里给账户增加可用余额。
这就是一个最简单的扣钱和加钱的TCC资源的设计。在扣钱TCC资源里,Try接口预留资源扣除
余额, Confirm接按凵空操作, Cancel接凵释放资源,增加余额。在加钱TC资源里,Try接凵无需
预留资源,空操作;Coηfirm接口直接增加余额; Cance丨接口无需释放资源,空操作
2.3账务系统模型并发控制
之前提到,设计一套TCC接口需要有两点,一点是需要拆分业务逻辑成两阶段完成。这个我们已经
介绍了。另外一点是要根据自身的业务模型控制并发
Seat框架本身仅提供两阶段原了提交协议,保证分布式事务原了性。事务的隔离需要交给业务逻辑
来实现。隔离的本质就是控制并发,防止并发事务操作相同资源而引起的结果错乱。
举个例子,比如金融行业里管理用户资金,当用户发起交易时,一般会先检查用户资金,如果瓷金充
足,则扣除相应交易金额,增加卖家资金,完成交易。如果没有事务隔离,用户同时发起两笔交易,
两笔交易的检查都认为资金允足,实际上却只够支付笔交易,结果两笔交易都支付成功,导致资损
可以发现,并发控制是业务逻辑执行正确的保证,但是像两阶段锁这样的并发访问控制技术要求一直
持有数据库资源锁直到整个事务执行结束,特别是在分布式事务架枃下,要求持有锁到分布式事务第
二阶段执行结束,也就是说,分布式事务会加长资源锁的持有时间,导致并发性能进一步下降。
因此,τcC模型的隔离性思想就是通过业务的改造,在第一阶段结束之后,从底层数据库资源层面的
加锁过渡为上层业务层面的加锁,从而释放底层数据库锁资源,放宽分布式事务锁协议,将锁的粒度
降到最低,以最大限度提高业务并发性能
还是以上面的例了举例,账户A上有100元,事务T1要扣除其中的30元,事务T2也要扣除
30元,出现并发″。在第一阶段Try操作中,需要先利用数据库资源层面的加锁,检査账户可用余
额,如果氽额充足,则预留业务资源,扣除本次交易金额,一阶段结束后,虽然数据库层面资源懺被
释放了,但这笔资金被业务隔离,不允许除本事务之外的其它并发事务动用
Part2:业务模型与并发控制
TCC设计-并发控制
扣钱场景为例:账户A上有100元,事T1要扣除其中的30元,事务T2也要扣除30元,出现并发
Iry:检查余额,预留旦中30元;
账户A:
T1扣除部分
T2扣除部分
可用余额
0
60
100
T1 Comfirm:空提交
账户A:
T2扣除部分
可用余额
50
100
T1 Cancel:释放T1预留的30元
账户A
可用会额
T2扣除部分
可用余额
SOFA Channel
14/39
并发的事务T2在事务τ1一阶段接口结東释放了数据库层面的资源锁以后,就可以继续操作,跟
事务T1一样,加锁,检査余额,扣除交易金额
事务T1和T2分别扣除的那一部分瓷金,相互之间无干扰。这样在分布式事务的二阶段,无论T1
是提交还是回滚,都不会对T2产生影响,这样T1和T2可以在同个账户上并发执行
大家可以感受下,一阶段结束以后,实际上采用业务加锁的方式,隔离账户资金,在第一阶段结束后
直接释放底层资源锁,该用户和卖家的其他交易都可以立刻并发执行,而不用等到整个分布式事务结
束,可以获得更高的并发交易能力。
这里稍微有点抽象,下面我们将会针对业务模型进行优化,大家可以更直观的感受业务加锁的思想。
2.4账务系统模型优化
前面的模型大家肯定会想,为啥一阶段就把钱扣除了?是的。之前只是为了简单说明TCC模型的设
计思想。在实际中,为了更好的用户体验,在第阶段,般不会直接把账户的余额扣除,而是冻结,
这样给用户展示的时候,就可以很清晰的知道,哪些是可用余额,哪些是冻结金额
那业务模型变成什么样了呢?如图所示,需要在业务模型中增加冻结金额字段,用来表示账户有多少
金额处以冻结状态。
Par2;业免模型与才发控制
aFA5Te2E
TCC设计-业务模型优化
扣钱场景为例:账户A上有100元,要扣涂其中的30元
Try:检查余额,预留其中30元;
账户A:
冻结部分
可用余额
Comfirm:扣除30元;
账户A
可用余额
30
100
Cancel:释放预留的30元
账户A:
可用余额
100
SOFA Channel
既然业务模型发生了变化,那扣钱和加钱的TCC接口也应该相应的调整。还是以前面的例子来说明。
在扣钱的TCC资源里。Ty接口不再是直接扣除账广的可用余额,而是真正的预留资源,冻结部分
可用余额,即减少可用余额,增加冻结金额。 Confirm接口也不再是空操作,而是使用Try接口预
留的业务资源,即将该部分冻结金额扣除;最后在 Cancel按口里,就是释放预留资源,把Try接口
的冻结金额扣除,增加账户可用余额。加钱的TCC瓷源由于不涉及冻结金额的使用,所以无需更改。
通过这样的优化,可以更直观的感受到τcC接口的预留资源、使用资源、释放资源的过程。
那并发控制又变成什么样了呢?跟前面人部分类似,在事务T1的第一阶段Try操作中,先锁定账
户,检査账户可用余额,如果余额充足,则预留业务瓷源,減少可用余额,増加冻结金额。并发的事
务T2类似,加锁,检查余额,减少可用余额金额,增加冻结金额。
(系统自动生成,下载前可以参看下载内容)
下载文件列表
相关说明
- 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
- 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度。
- 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
- 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
- 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
- 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.