1.TCC 介绍
TCC属于2阶段分布式事务
TCC是Try-尝试、Confirm-确认、Cancel-取消
- Try:尝试阶段,对资源进行锁定
- Confirm:确认阶段,对资源进行确认,完成操作
- Cancel:取消阶段,对资源进行还原,取消操作
2.案例介绍
假设我们的产品有两个服务,分别是订单服务和库存服务,假设张三买了10瓶可乐,消费30元,如果放在TCC中会变成什么样子呢?
注意:TCC的设计是需要改动表结构才可以的
如下案例:
订单服务:在原有的三个字段外,增加了预增金额和状态字段
库存服务:在原有的两个字段外,增加了冻结库存字段
2.1.Try阶段:锁定阶段
变更数据放入到新增字段中,对资源进行冻结
2.2.Confirm:确认阶段
要是订单服务业务逻辑和库存服务业务逻辑都是按照预期的业务流程正确的执行
(1)那此时订单表张三的预增金额被改为0,原本的30被挪到了真正的订单金额字段,状态从刚才的初初始变更为完成,说明订单表已经处理完毕了
(2)把当前库存和冻结的库存进行相减,可乐的库存就变成了90瓶
2.3.Cancel:取消阶段
取消阶段就是把之前冻结的资源进行释放
(1)订单的状态就变成了取消代表是无效的,预增金额从刚才的30转换成了0,实际的订单金额不会产生任何的变化
(2)原本被冻结的10个库存在这里进行了释放
3.
- TCC 设计之初认为Confirm与Cancel一定会成功
- Confirm与Cancel尽可能不要产生服务通信,以及任何业务逻辑的判断,在Try的阶段应该把90%的工作都做完,在C/C阶段只做最简单的事情。
- Confirm与Cancel如果失败,冻结的资源没有释放,则由事务中间件进行”重试”补偿,尽量保证C/C阶段能够执行成功
- 极小概率情况下,C/C会出现彻底失败失败的情况,比如正好在更新这个数据的时候服务器掉电了,数据库崩溃了,这个时候依靠软件自动恢复显然是不可能的,我们就需要定时任务检测或人工介入(掏底策略)
TCC方案是一种概念性的设计,我们放到了不同数据库或者放到了不同分布式事务中间件,他们具体落地的理念也是不同的。
4.Seata在TCC模式下的应用
4.1.Seata体系三个角色
事务管理器(TM):决定什么时候全局提交/回滚(司令官)
事务协调者(TC):负责通知命令的中间件Seata-Server(传令官)
资源管理器(RM):做具体事儿的工具人(大头兵)
4.2.Seata 下TCC执行流程
(1)TM 业务逻辑方法,在进入方法前就会自动的向TC,发起一个开启全局事务的通知,这样Seata就会分配一个全局事务编号
(2)随着TM方法依次向下执行过程中,比如新增一个订单,那么这个订单服务就是资源管理器RM,在这个过程中每一个RM就分成了三个子部分,每个子部分对应了TCC的一个阶段,就是叫的名字不同而已
Prepare:对应了TCC的Try准备阶段
Commit:对应了TCC的Confirm确认阶段
Rollback:对应了TCC的Cancel取消阶段
(3)TM在执行的时候,首先来调用了订单服务,订单服务在Prepare中有对应的方法,在这个方法中像我们刚才演示表那样来锁定相关的金额资源,将当前订单的状态制为初始阶段
(4)RM执行完成之后,自动的向TC上报分支事务,因为一个总的分布式事务,一定包含多个分支事务,每一个RM都对应至少一个分支事务,上报的作用是由TC分配给当前RM一个分支事务编号,同时Prepare阶段会定时的向TC上报我们自己服务的状态,已保证系统的可用性
(5)TM从上到下依次执行所有RM方法,当都调用完成之后,此时有两种可能。
- 业务逻辑方法执行成功:TM向TC提交一个全局提交的请求,在由TC向RM下达commit操作,用于把之前冻结的数据来进行一个解冻
- 业务逻辑方法执行失败:TM在业务过程中出现了任何运行时异常,就会自动的向TC来上报回滚,一旦上报回滚以后,TC就会向所有RM下达分支事务回滚操作,Rollback阶段就把刚才冻结的资源进行清零操作,进行事务的全局回滚
这个过程中还涉及到了很多细节,详情移步seata官网,了解详细的实现方案以及代码部分。
seata官网:https://seata.io/zh-cn/
5.方案特点
性能:好
模式:AP,存在数据不⼀致的中间状态
难易程度:复杂,SEATA TC只负责全局事务的提交与回滚指令,具体的回滚处理全靠程序员⾃⼰实现
6.使⽤要求:
所有服务与数据库必须要⾃⼰拥有管理权
⽀持异构数据库,可以使⽤不同选型实现
7.应⽤场景:
⾼并发互联⽹应⽤,允许数据出现短时不⼀致,可通过对账程序或补录来保证最终⼀致性。
转载请注明:西门飞冰的博客 » 分布式事务之TCC方案