分布式协议与算法实战
韩健
腾讯资深工程师
23193 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
分布式协议与算法实战
15
15
1.0x
00:00/00:00
登录|注册

加餐 | TCC如何实现指令执行的原子性?

撤销操作
确认操作
预留操作
撤销操作
确认操作
预留操作
撤销操作
确认操作
预留操作
Cancel(撤销)
Confirm(确认)
Try(预留)
为什么TCC能解决指令执行的原子性问题?
避免数据库层面的二阶段提交协议长时间锁定资源
TCC的跨数据库、跨业务系统实现资源管理
TCC是一种设计模式
TCC的编程开发工作量
TCC与XA规范的区别
确认、撤销操作需要支持幂等性
操作3
操作2
操作1
TCC包含的预留、确认或撤销这 2 个阶段
课堂思考
内容小结
如何通过TCC指令执行的原子性?
什么是TCC?
TCC如何实现指令执行的原子性?

该思维导图由 AI 生成,仅供参考

你好,我是韩健。
在上一讲我提到,虽然 MySQL XA 能实现数据层的分布式事务,解决多个 MySQL 操作的事务问题,但我现在负责的这套业务系统还面临别的问题:在接收到外部的指令后,我需要访问多个内部系统,执行指令约定的操作,而且,还必须保证指令执行的原子性(也就是事务要么全部成功,要么全部失败)。
那么我是如何实现指令执行的原子性呢?答案是 TCC。
在我看来,上一讲中,基于二阶段提交协议的 XA 规范,实现的是数据层面操作的事务,而 TCC 能实现业务层面操作的事务。
对你来说,理解了二阶段提交协议和 TCC 后,你可以从数据层面到业务层面,更加全面理解如何实现分布式事务了,这样一来,当你在日常工作中,需要实现操作的原子性或者系统状态的一致性时,就知道该如何处理了。
那么为了帮助你更好地理解 TCC,咱们还是先来看一道思考题。
我以如何实现订票系统为例,假设现在要实现一个企鹅订票系统,给内部员工提供机票订购服务,但在实现订票系统时,我们需要考虑这样的情况:
我想从深圳飞北京,但这时没有直达的机票,要先定深圳航空的航班,从深圳去上海,然后再定上海航空的航班,从上海去北京。
因为我的目的地是北京,所以如果只有一张机票订购成功,肯定是不行的,这个系统必须保障 2 个订票操作的事务要么全部成功,要么全部不成功。那么该如何实现 2 个订票操作的事务呢?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

TCC是一种业务层面的分布式事务协议,与XA规范相比,TCC更适用于实现业务层面操作的事务。TCC包含预留、确认和撤销三个操作阶段,通过这些操作来实现指令执行的原子性。在实际应用中,TCC需要根据具体场景特点和业务逻辑来设计相应的操作,因此与MySQL XA相比,需要更多的编程开发工作量。TCC的实现不受限于任何技术,是一种设计模式,适用于各种技术方案。由于TCC的每个操作对于数据库来说都是一个本地数据库事务,因此在操作结束时,相关的数据库资源会被释放,避免了长时间锁定资源导致系统性能低下的问题。总之,TCC能够跨数据库、跨业务系统实现资源管理,满足复杂业务场景下的事务需求。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《分布式协议与算法实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(17)

  • 最新
  • 精选
  • Dovelol
    老师好,想问下,如果有3个服务调用,都会涉及到update数据库等操作,那预留资源具体是怎么预留的呢?开启事务,修改,不commit?然后等着commit请求过来后在commit数据库事务吗?

    作者回复: 加一颗星:),可以引入一个额外字段,在预留阶段,更新额外字段的值,在确认阶段,将额外字段的值更新到原计划更新的那个字段。

    2020-06-29
    5
    15
  • hello
    老师,再请教您一个问题,TCC有什么好的开源实现可供借鉴没?

    作者回复: 加一颗星:),tcc-transaction、seata等,可以了解下。

    2020-06-29
    4
    13
  • Corner
    首先感谢老师长久以来坚持持续加餐和优化。然后有一个问题需要请教一下,在预留阶段有哪些常用的数据处理手段呢?是否数据上都要为预留操作增加相应的字段标记。

    作者回复: 加一颗星:),比如,可以通过状态位、标志位来标记。

    2020-06-30
    7
  • hello
    老师,请教您一个问题,您文中举例操作1,操作2,操作3这三个操作都各自实现TCC(预留操作、确认操作、撤销操作),那TCC都是针对单个操作(如针对操作1、操作2、操作3)实现,那要实现操作1+操作2+操作3这三个操作要么全成功,要么全失败如如何达到的?

    作者回复: 加一颗星:),如果三个操作的预留操作都成功了,就执行对应的确认操作,如果有任何一个不成功,就执行“已执行成功的预留操作”对应的撤销操作,这样,都回到了最初的状态。

    2020-06-29
    3
    6
  • kylexy_0817
    韩老师辛苦了。想问题下,在项目中使用TCC,是否需要额外的点存放着数据变更前的快照呢?因为好让在cancel的时候恢复?

    作者回复: 加一颗星:),可以的

    2020-10-18
  • dra
    良心课程,老师用心了。专栏虽完结,还在不停加餐,为学员提供知识服务
    2020-06-28
    1
    9
  • Geek_7a6fde
    原文问题:我提到了自己通过 TCC 解决了指令执行的原子性问题。那么你不妨想想,为什么 TCC 能解决指令执行的原子性问题呢? 个人理解回答:TCC的try阶段可以预留或者锁定资源,就当于对该资源加锁,加锁了肯定就可以保证原子性了,confirm或cancel就是相当于释放锁
    2021-10-07
    1
  • Heaven
    在执行的过程中,TCC利用了二阶段提交的思想,既能够锁定成功,就相当于收到了锁定的确认操作,只有在所有的锁定确认收到了,才可以继续执行Confrim操作,在执行Confrim操作的时候,就不允许失败的存在,即使挂了,也会有后来人再上线的时候重新顶替上去
    2020-08-21
    1
  • Psyduck
    非常感谢老师,之前在看 TCC 时还是很模糊的感觉,通过这篇文章的讲解感觉清晰多了。
    2020-07-01
    1
  • i_chase
    也就是说,tcc做了如下假设:预留资源成功了,那么confirm/cancel就一定是成功的?
    2022-12-18归属地:广东
收起评论
显示
设置
留言
17
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部