上一次我们讲解了分布式事务的 2PC、3PC 。那么这次我们来理一下 TCC 事务。本次还是讲解 TCC 的原理跟 .NET 其实没有关系。

TCC

  • Try 准备阶段,尝试执行业务
  • Confirm 完成业务
  • Cancel 回滚准备阶段的业务

TCC 事务其实是 2PC 的一个扩展。上一次我们说了 2PC ,在二阶段进行事务提交。因为 2PC 基本上是利用数据库的

事务能力进行 commit ,其实这里还有可能出现一种 rollback 情况。 TCC 就是把 2PC 的二阶段细化了,拆分成了 Confirm 跟 Cancel 两个步骤。TCC 是 2PC 的一次进化,TCC 拆分二阶段后已经不局限于数据库事物了,它可以适用于非数据库事物的场景。因为我们的 Cancel 阶段可以进行更加复杂的回滚能力,业务补偿能力。TCC 可以认为是业务层面的2PC 。

下面我们以使用客户积分兑换房间为示例说明一下 TCC 事务。

  1. Try

    为完成 TCC 事务的 Try 阶段,我们需要在房间上增加一个状态字段“是否锁定”,一旦锁定,其它订单就没有办法预定这间房间。同样我们需要在用户积分表上增加一个字段“冻结积分”,如果涉及到并发可能要单独拉一张表出来。这里简化一点就加个字段吧。

    Try阶段开始:订单服务把房间设置为锁定状态;积分服务把用户的积分减去消耗的积分同时把消耗的积分暂存在冻结字段上。
  2. Confirm

    如果一阶段都提交成功了,那么所有的服务都开始进入 Confirm 阶段。订单服务把房间状态更改为“已预定”状态;积分服务把冻结的积分清0。这样整个事务都成功完成了。
  3. Cancel

    如果一阶段某个服务没有 Try 成功,那么所有的服务都要进入Cancel阶段。比如订单服务锁定房源成功了,积分冻结的时候失败了,那么订单服务要进入 Cancel 阶段,把房间的的锁定状态取消,从新释放出来。如果锁定房源失败了,积分扣减成功了,那么 Cancel 阶段就要把扣减的积分给加回去。

TCC 的一些问题

异常

如果 Confirm 阶段出现异常,TCC 管理器会不断的重试这个阶段,直到成功。因为理论上认为只要 Try 是成功的,那么 Confirm 阶段一定会成功。因为所需要的资源已经在 Try 阶段冻结了。如果 Cancel 阶段出现异常,那么 TCC 管理器也会不断的重试这个阶段来解除冻结的资源。

冥等

因为 TCC 有重试机制,所以所有的接口都需要实现幂等,避免多次调用对业务数据产生错误。比如多次扣款,多次下订单等。

并发问题

因为 TCC 事务在 Try 阶段对资源是完全的提交状态,并没有像 2PC 那样使用数据库事物来对资源进行锁定,所以在并发的时候对资源的修改要格外注意。在处理业务的时候要时刻注意锁定的资源对业务造成的一影响。

允许空取消

TCC 事务在一阶段 Try 的时候失败要运行进行 Cancel 提交。这时候 Cancel 其实是不需要做任何补偿操作,我们称之为空取消。这个时候也要注意,在编写 Cancel 操作的时候要时刻注意到底有没有完成 Try 操作,如果没有完成 Try 操作则要进行空取消。

预付悬挂

TCC 按流程上来说是不会出现悬挂情况的。但是有一种特殊情况会造成资源的悬挂。按照正常流程我们的 Try 阶段总是先于 Cancel 执行的。但是由于网络拥堵的问题造成 Try 调用延迟了,TCC 管理器在一定时间没收到 Try 成功响应后会发送 Cancel 调用,这个 Cancel 就有可能在 Try 之前先被调用了。在 Cancel 执行成功后, 这个 Try 请求调用才到达服务,这个时候如果 Try 被执行成功,那么就会造成资源的悬挂。所以当编写 Try 代码的时候同意需要注意是不是已经调用过 Cancel 操作了。

总结

TCC 事务是 2PC 的一种升级。TCC 相对于 2PC 不再依赖于本地数据库事物能力,它可以使用于应用层面的事务。它把 2PC 的提交跟回滚操作明确的抽象成 Confirm 跟 Cancel 。TCC 事务在逻辑上是比较清晰的。但是 TCC 使用起来也有不方便的地方,就是它对代码入侵比较强,比较繁琐。每个业务都要强制拆分成3个方法。而且还要还要注意幂等,空取消,悬挂等问题。

相关文章

NET Core with 微服务 - 什么是微服务

.Net Core with 微服务 - 架构图

.Net Core with 微服务 - Ocelot 网关

.Net Core with 微服务 - Consul 注册中心

.Net Core with 微服务 - Seq 日志聚合

.Net Core with 微服务 - Elastic APM

.Net Core with 微服务 - Consul 配置中心

.Net Core with 微服务 - Polly 熔断降级

.Net Core with 微服务 - 分布式事务 - 2PC、3PC

关注我的公众号一起玩转技术

.Net Core with 微服务 - 分布式事务 - TCC的更多相关文章

  1. .Net Core with 微服务 - 分布式事务 - 可靠消息最终一致性

    前面我们讲了分布式事务的2PC.3PC , TCC 的原理.这些事务其实都在尽力的模拟数据库的事务,我们可以简单的认为他们是一个同步行的事务.特别是 2PC,3PC 他们完全利用数据库的事务能力,在一 ...

  2. .Net Core with 微服务 - 分布式事务 - 2PC、3PC

    最近比较忙,好久没更新了.这次我们来聊一聊分布式事务. 在微服务体系下,我们的应用被分割成多个服务,每个服务都配置一个数据库.如果我们的服务划分的不够完美,那么为了完成业务会出现非常多的跨库事务.即使 ...

  3. Spring Cloud Alibaba | 微服务分布式事务之Seata

    Spring Cloud Alibaba | 微服务分布式事务之Seata 本篇实战所使用Spring有关版本: SpringBoot:2.1.7.RELEASE Spring Cloud:Green ...

  4. 微服务分布式事务之LCN、TCC

    在亿级流量架构之分布式事务解决方案对比中, 已经简单阐明了从本机事务到分布式事务的演变过程, 文章的最后简单说明了TCC事务, 这儿将会深入了解TCC事务是原理, 以及理论支持, 最后会用Demo举例 ...

  5. [跨数据库、微服务] FreeSql 分布式事务 TCC/Saga 编排重要性

    前言 FreeSql 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/Gbase/神通/人大金仓/翰高/Clickhouse/MsAcc ...

  6. .Net Core with 微服务 - 使用 AgileDT 快速实现基于可靠消息的分布式事务

    前面对于分布式事务也讲了好几篇了(可靠消息最终一致性 分布式事务 - TCC 分布式事务 - 2PC.3PC),但是还没有实战过.那么本篇我们就来演示下如何在 .NET 环境下实现一个基于可靠消息的分 ...

  7. spring cloud+dotnet core搭建微服务架构:服务发现(二)

    前言 上篇文章实际上只讲了服务治理中的服务注册,服务与服务之间如何调用呢?传统的方式,服务A调用服务B,那么服务A访问的是服务B的负载均衡地址,通过负载均衡来指向到服务B的真实地址,上篇文章已经说了这 ...

  8. spring cloud+dotnet core搭建微服务架构:配置中心续(五)

    前言 上一章最后讲了,更新配置以后需要重启客户端才能生效,这在实际的场景中是不可取的.由于目前Steeltoe配置的重载只能由客户端发起,没有实现处理程序侦听服务器更改事件,所以还没办法实现彻底实现这 ...

  9. spring cloud+dotnet core搭建微服务架构:Api授权认证(六)

    前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...

随机推荐

  1. XML技术

    XML是一种可扩展标记语言,用来标记数据.定义数据类型,1998年由W3W发布1.0.版本,与HTML语言相比,可以自定义可扩展标签格式,但是语法严格. XML可以用来存储数据,可移植性强,主要充当配 ...

  2. k8s之deployment详解

    Deployment介绍 为了更好地解决服务编排的问题,k8s在V1.2版本开始,引入了deployment控制器,值得一提的是,这种控制器并不直接管理pod, 而是通过管理replicaset来间接 ...

  3. C语言:数组长度的检测方法

    //数组长度的检测方法 #include <stdio.h> int main() { int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5 ...

  4. ssh保持长连接的方式

    方法有以下三种:1.修改server端的etc/ssh/sshd_configClientAliveInterval 60 #server每隔60秒发送一次请求给client,然后client响应,从 ...

  5. Optional 的使用会导致性能下降吗?

    几天前,我在论坛上发了一篇关于Optional 的文章.其中一条评论是一个非常好的问题: Optional 的使用会导致性能下降吗? 答案是: 是的,它会的.但是你应该担心吗? 使用Optional的 ...

  6. 如何进行TIDB优化之Grafana(TiDB 3.0)关注监控指标

    前言 在对数据库进行优化前,我们先要思考一下数据库系统可能存在的瓶颈所在之外.数据库服务是运行在不同的硬件设备上的,优化即通过参数配置(不考虑应用客户端程序的情况下),而实现硬件资源的最大利用化.那么 ...

  7. c# checkedListBox设置多列横向显示 经验总结

    1. 设置checkedListBox的MultiColumn 属性为true; 2. 调整checkedListBox的宽度,调整ColumnWidth的宽度

  8. 【洛谷P1816 忠诚】线段树

    题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了 ...

  9. windows7查看和关闭占用的端口

    1. 查看占用的端口 cmd 后输入命令:netstat -aon|findstr [要查的端口] 如欲查端口1099,输入:netstat -aon|findstr 1099 2. 关闭占用的端口 ...

  10. Vulnhub -- DC2靶机渗透

    信息收集 nmap开始扫描 只开了80端口,直接打开ip地址发现无法打开网页,但是进行了域名的跳转 !这里发现了一个问题,其实还开了一个7744端口,但是使用-sV的方式是扫描不出来的,使用-p-后可 ...