了解下五种TCC分布式事务编程模型

大家好,我是小趴菜,在单机服务下,Spring自带的事务就可以满足我们的需求了,但是在分布式下,Spring的事务就没法保证我们的数据可靠性,这时候我们就需要引入分布式事务,TCC就是其中一种分布式事务解决方案

TCC共有三个阶段

. try:尝试阶段

. confirm:确认阶段

. cancel:回滚阶段

我们还是以最经典的转账案例,我们需要知道在整个转账过程到结束,TCC的每一个阶段都做了些什么事

TCC模型-1(错误)

在try阶段,两个人都不做操作,在confirm阶段进行扣钱和加钱操作,cancel回滚阶段也是什么都不做

首先这个模式是错误的,为什么呢?

try阶段什么都不做,那么在confirm阶段的时候就会出现问题,比如张三的余额不足20了,这时候肯定会就扣减失败,但是李四加20元是成功的。这时候即使会回滚,但是会发现,cancel阶段没有做任何操作,所以就会出现张三钱没扣,但是李四的账户多了20元

而之所以会出现这个问题,主要是没有提前判断章三的账户是否余额充足

TCC模型-2(错误)

针对模型一的问题,这时候在try阶段我们首先判断张三的金额是否充足,然后在confirm阶段进行扣减金额,这时候是不是就不会出现模型一的问题了。

首先这个模型还是错误的。

假设张三现在还有20元,但是这时候有二笔扣款操作,每笔20元。但是在try阶段只是判断金额是否大于等于20,所以二个操作在try阶段都会成功。

但是在confirm阶段,由于张三的金额只有20元,所以肯定会有一笔扣款操作会失败,但是李四加钱是会成功的。这时候又会出现模型一的问题,张三扣钱失败,但是李四加钱成功了。即使回滚,李四的钱也不会有变化,所以到最后,李四的钱就会莫名其妙多20

而之所以会出现这个问题是由于并发导致的,二个线程同时来执行扣款请求,这时候try阶段都会成功,所以才导致有一笔操作在confirm失败

TCC模型-3(错误)

针对模型二的并发问题,这时候我们在try阶段先扣减张三的20元,同时将李四的账户加20元,如果执行成功,confirm阶段就什么都不做,cancel回滚阶段就还张三20,扣减李四40

这时候我们好像是已经解决了在并发情况下,张三因为余额不足而导致的一次失败操作

但是此时我们在try阶段是直接将李四的金额加了20,此时还没有执行confirm阶段的操作,这时候正好有一个线程B来操作李四的账户,比如扣减操作,假设李四本来的金额是只有10块,这个时候线程B来扣减李四的账户20元,正常来说,我们给李四增加20元的这个TCC事务还没有完成,也就是还没有执行confirm阶段,但是线程B这时候来发现李四账户有30了,可以扣减20元

这时候问题来了,我们这个TCC事务执行了try阶段,李四的金额从10变成了30,线程B发现李四账户有30元,就扣减了20,这时候由于某些原因,导致这个TCC事务失败了,那么就会执行cancel阶段的操作,但是此时李四账户因为线程B扣了20,所以只剩10块。这时候难道要从10扣减成-10吗?

而之所以会出现这个问题就是由于脏读导致的,因为第一个线程还没有提交,导致其它线程读到了脏的数据

TCC模型-4(正确,标准的TCC模型)

针对模型三的脏读问题,我们在try阶段就不对李四账户做操作,此时也只是冻结张三的20元, 如果try阶段成功,那么confim阶段就会将对应张三账户扣减冻结20元,李四也会加20元,即使失败了,执行了cancel操作,也只是将张三冻结的20元返还而已

TCC模型-5(正确,高效的TCC模型)

为什么这个模型相较于模型四更高效呢,业务的操作百分之九十以上其实都会成功,也就是说大部分的请求都会执行confirm阶段,相对于模型四而言,confirm阶段多了一步扣减张三冻结的20元的数据库操作,模型五相对来说就减少了一步数据库的操作

相关推荐
在未来等你3 分钟前
Elasticsearch面试精讲 Day 12:数据建模与字段类型选择
大数据·分布式·elasticsearch·搜索引擎·面试
a5876932 分钟前
消息队列(MQ)初级入门:详解RabbitMQ与Kafka
java·分布式·microsoft·面试·kafka·rabbitmq
考虑考虑35 分钟前
Postgerssql格式化时间
数据库·后端·postgresql
千里码aicood44 分钟前
【springboot+vue】党员党建活动管理平台(源码+文档+调试+基础修改+答疑)
java·数据库·spring boot
Chan161 小时前
【智能协同云图库】基于统一接口架构构建多维度分析功能、结合 ECharts 可视化与权限校验实现用户 / 管理员图库统计、通过 SQL 优化与流式处理提升数据
java·spring boot·后端·sql·spring·intellij-idea·echarts
先做个垃圾出来………1 小时前
差分数组(Difference Array)
java·数据结构·算法
库库林_沙琪马1 小时前
REST接口幂等设计深度解析
spring boot·后端
BillKu1 小时前
Java核心概念详解:JVM、JRE、JDK、Java SE、Java EE (Jakarta EE)
java·jvm·jdk·java ee·jre·java se·jakarta ee
IT_陈寒1 小时前
Redis性能提升50%的7个关键优化策略,90%开发者都不知道第5点!
前端·人工智能·后端
智商偏低1 小时前
ASP.NET Core 身份验证概述
后端·asp.net