基于RESTful API的TCC补偿模式 分布式事务

互联网大厂Java面试现场:谢飞机的“起飞”之旅(Spring Boot、微服务、Redis、JVM、线程池、分布式事务) Java程序员谢飞机面试互联网大厂,技术涵盖Spring Boot、JVM、Redis、线程池、分布式事务等,适合小白学习面试技巧与技术点。 阅读详情

前言

本例基于Atomikos提出的微服务分布式事务的解决方案, 该方案建立在更加轻量级的HTTP协议之上, 原文如下

TCC for transaction management across microservices

根据Try Confirm Cancel补偿模式, 有关于spring Cloud的实战如下

https://github.com/prontera/spring-cloud-rest-tcc

示例场景

一个简单的TCC应用如下: 图中蓝色方框Booking Process代表订票系统, 该系统分别对swiss和easyjet发起预留机票资源的请求

  1. 在步骤1.1对”swiss”发起Try预留请求. 服务提供方”swiss”将会等待Confirm操作, 如果超时那么就将会被自动撤销(Cancel)并释放资源. 确认资源的入口就是URI R1的HTTP PUT请求.

  2. 在步骤1.2中, 使用URI R2对”easyjet”作出如第一点中一样的预留资源操作

  3. 在步骤1.3中, Booking Process现在可以通过协调器(Coordinator)服务发起对上述两个预留资源的确认(Confirm)操作. 并且, 资源协调服务会处理相关服务的确认或者补偿操作.

    如果在第3步之前有任何异常, 那么所有预留资源将会被Cancel或者等待超时然后被自动撤销. 如果是在第3步Confirm之后才出现异常, 那么所有的资源都不会受到影响. 在第3步中发生的异常都会由Coordinator服务处理, 包括因为宕机或者是网络抖动所引起的恢复重试. 对REST服务提供了事务保证.

角色

这套API由3个角色组成: 参与者角色, 协调者角色和应用程序.

  • 参与者是特指那些实现了TCC柔性事务的应用程序, 就正如本示例中的”swiss”和”easyjet”
  • 协调者角色是特指那些管理一组相关参与者的服务调用, 如Confirm, Cancel操作, 在本示例中是”Transaction Coordinator”
  • 应用程序, 这里我称之为请求方, 除了需要使用协调器外无其他要求, 如本示例中的”Booking Process”

TCC服务提供方: 参与者API

参与者职责

参与者负责管理特定的业务资源. 默认情况下业务预留资源在一定时间后会超时, 除非该预留资源被协调器所确认.

自动超时和撤回

每一个参与者的实现必须有自动Cancel超时资源的功能. 除非参与者接收到确认消息, 否则没有资源是不会过期的.

资源操作的入口

每个参与者的实现必须返回一个用于调用Confirm的链接. 这些链接可以包含Confirm的URI, 自动过期时间等元数据. 下面是一个简单例子

{
  "participantLink":
    {"uri":"http://www.example.com/part/123",
    "expires":"2014-01-11T10:15:54Z"
    }
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

实际上例子中的JSON只是建议格式, 真实使用的时候完全取决于双方的通信格式.

PUT to Confirm

在上述参与者返回的用于确认的链接中, 必须支持PUT方法以用于确认. 由于网络抖动等情况, 该操作必须具备幂等性.

PUT /part/123 HTTP/1.1
Host: www.example.com
Accept: application/tcc
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

注意请求头中MIME类型, 暗示了客户端的语义期望(可根据实际情况选择是否实现该MediaType). Confirm操作通常由协调者调用.

尽管参与者提供的API有指定的MIME类型, 但是这个类型仅仅用于指明语义, 实际上并不需要request body与response body.

如果一切正常, 那么参与者的响应如下

HTTP/1.1 204 No Content
 
  • 1
  • 1

如果Confirm请求送达参与者后发现预留资源早就被Cancel或者已经超时被回滚, 那么参与者的API必须返回404错误

HTTP/1.1 404 Not Found
 
  • 1
  • 1

DELETE to Cancel: 可选实现

每个参与者URI**或许**会有实现DELETE方法去显式地接受撤销请求. 由于网络抖动等情况, 该操作必须具备幂等性.

DELETE /part/123 HTTP/1.1
Host: www.example.com
Accept: application/tcc
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

如果补偿成功则返回

HTTP/1.1 204 No Content
 
  • 1
  • 1

因为参与者有实现自动撤销超时资源的职责, 那么如果在显式地调用Cancel的时候有其他错误发生, 那么这些错误都可以被忽略而且不影响整体的分布式事务

在内部事务已经超时或者已经被参与者自身补偿之后, 那么他可以直接返回404

HTTP/1.1 404 Not Found
 
  • 1
  • 1

因为DELETE请求是一个可选操作, 有些参与者可能没有实现这个功能, 在这个情况下可以返回405

HTTP/1.1 405 Method Not Allowed
 
  • 1
  • 1

GET方法故障诊断: 可选实现

参与方服务可以实现GET方法来用于故障的诊断. 但是这个超出了REST TCC的简约协议的意图, 所以这个功能就由实际情况来决定是否实现

协调器API: 面向请求方的开发者

协调器服务是由我们实现, 并交由请求方的开发人员使用. 因为这里从使用RESTful接口的设计角度来说明, 而不讨论协调器的内部实现.

协调器职责

  1. 对所有参与者发起Confirm请求
  2. 无论是协调器发生的错误还是调用参与者所产生的错误, 协调器都必须有自动恢复重试功能, 尤其是在确认的阶段.
  3. 能判断有问题的Confirm操作的原因
  4. 方便地进行Cancel操作

PUT to Confirm

请求方对协调器发出PUT请求来确认当前的分布式事务. 这些事务就是参与者之前返回给请求方的确认链接

PUT /coordinator/confirm HTTP/1.1
Host: www.taas.com
Content-Type: application/tcc+json
{
  "participantLinks": [
     {
     "uri": "http://www.example.com/part1",
     "expires": "2014-01-11T10:15:54Z"
     },
     {
     "uri": "http://www.example.com/part2",
     "expires": "2014-01-11T10:15:54+01:00"
     }
  ]
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

然后协调器会对参与者逐个发起Confirm请求, 如果一切顺利那么将会返回如下结果

HTTP/1.1 204 No Content
 
  • 1
  • 1

如果发起Confirm请求的时间太晚, 那么意味着所有被动方都已经进行了超时补偿

HTTP/1.1 404 Not Found
 
  • 1
  • 1

最最最糟糕的情况就是有些参与者确认了, 但是有些就没有. 这种情况就应该要返回409, 这种情况在Atomikos中定义为启发式异常

HTTP/1.1 409 Conflict
 
  • 1
  • 1

当然, 这种情况应该尽量地避免发生, 要求Confirm与Cancel实现幂等性, 出现差错时协调器可多次对参与者重试以尽量降低启发性异常发生的几率. 万一409真的发生了, 则应该由请求方主动进行检查或者由协调器返回给请求方详细的执行信息, 例如对每个参与者发起故障诊断的GET请求, 记录故障信息并进行人工干预.

PUT to Cancel

一个撤销请求跟确认请求类似, 都是使用PUT请求, 唯一的区别是URI的不同

PUT /coordinator/cancel HTTP/1.1
Host: www.taas.com
Content-Type: application/tcc+json
{
  "participantLinks": [
     {
     "uri": "http://www.example.com/part1",
     "expires": "2014-01-11T10:15:54Z"
     },
     {
     "uri": "http://www.example.com/part2",
     "expires": "2014-01-11T10:15:54Z"
     }
  ]
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

唯一可预见的响应就是

HTTP/1.1 204 No Content
 
  • 1
  • 1

因为当预留资源没有被确认时最后都会被释放, 所以参与者返回其他错误也不会影响最终一致性

构建开放可扩展系统:从API设计到微服务架构的实战指南 在软件工程领域,系统的开放性与可扩展性是支撑业务长期演进的核心架构能力。其原理在于通过定义清晰的边界和契约,将变化隔离在特定模块,从而在外部需求与内部实现之间建立缓冲层。这种设计的技术价值在于能有效应对业务不确定性、提升团队协作效率,并有机会构建平台生态。具体到技术实现,通常涉及API契约设计、标准化协议与数据格式,以及微服务与事件驱动等架构模式。在实际应用场景中,开放系统通过提供多语言SDK和完备文档降低接入成本,而可扩展架构则依赖无状态设计、读写分离与分库分表来应对流量与数据增长。本文聚焦于如何将开放与 阅读详情

相关推荐

SpringCloud面试题----微服务开发如何处理通信和数据一致性问题

SpringCloud面试题----微服务开发如何处理通信和数据一致性问题

qq_38737545的博客 494

补偿机制的实现

在日常开发中,经常需要跟对接第三方,一般场景下,失败了我们会直接把异常抛出,某些业务场景,失败了需要进行重试,而不是直接抛出异常,影响用户体验。

qq_22918201的博客 869

HZero微服务治理平台:从架构原理到企业级实践全解析

微服务架构通过将单体应用拆分为独立部署、松耦合的服务,提升了系统的可扩展性和团队开发效率,但其治理复杂度也随之增加。其核心原理在于服务间的通信、协调与状态管理,技术价值体现在支持快速迭代、技术异构和弹性伸缩。在实际应用场景中,服务发现、配置管理、权限控制和分布式事务等成为关键挑战。本文聚焦于HZero这一开源微服务治理平台,它基于Spring Cloud Alibaba深度定制,提供了身份服务、平台服务等核心模块,并内置多租户架构支持。通过集成Seata处理分布式事务,结合Docker与Kubernetes

cuanwei9356的博客 476

分布式接口调用,补偿机制如何设计

对于现在的大多数应用来说,基本上都是分布式的,单一应用的系统已经很少见了,那么对于分布式系统服务,我们总会遇到接口失败的情况,而对于这种情况,会根据返回结果类型来做不同处理,而我们今天要讨论的就是有限时间内重试的机制,该如何设计。 首先我们的思路肯定是循环尝试,是否已经到了指定时长,比方说3分钟,那么在第一次调用失败以后,我们应该在3分钟内多次尝试接口调用,如果成功则返回,如果一直失败超过3分钟...

Seeker-Wu的专栏 4652

数字图像处理基础实验(二):直方图均衡化

一、实验内容及原理 1、计算灰度图像的归一化直方图 具体内容:利用 OpenCV 对图像像素进行操作,计算归一化直方图.并在 窗口中以图形的方式显示出来 步骤: (1)初始化一个256大小的数组,存放图像中每级灰度值的像素点的个数 (2)遍历整张图像 (3)归一化数组 2、灰度图像直方图均衡处理 具体内容:通过计算归一化直方图,设计算法实现直方图均衡化处理。 步骤: (1)读取该像素点的灰度值 (...

lyd1995的博客 4528

pagerank算法详解

目录一、pagerank定义两个重要假设二、pagerank算法公式定义计算演示矩阵化计算三、存在的两个问题问题1.Dead Ends问题2.Spider Traps 一、pagerank定义 入链数:指向该节点的链接数 出链数:由该节点指出的链接数 以上图为例:A的入链数为1,出链数为3,所以将由A指向其他节点的边权重设置为1/3,表示A访问B、C、D节点的概率均为1/3 两个重要假设 数量假设:在Web图模型中,如果一个页面节点接收到的其他网页指向的入链数量越多,那么这个页面越重要。 质量假设:指向

gary101818的博客 4万+

java spring 实现接口发送记录和补偿操作

接口补偿操作

i_am_bad_man的博客 802

模电专题-MOS管的放大电路分析

在实际应用中,我们经常会使用到功率MOS,这时通常不会将它当成一个开关使用,而是当成一个放大器来使用,那这就需要让其工作在放大状态。参考下图中的mos管的特性曲线,右图中的输出特性曲线中有一根红色的分界线,这个线就是区分mos管工作状态的分界线,在红线的左边,mos管工作在可变电阻区,也就是线性区;在红线的右边mos管工作在恒流区,也就是饱和区。当然,还有一个截止区。本文分析主要运用模电课本中的理论计算验证。

Anitawen的博客 2万+

java 异常补偿解决_第三方接口调用异常补偿机制实现实例记录

背景:我们的组件(简称A),在业务链中属于数据支撑节点。其中与组件B存在接口同步数据的直接关系(API接口直接调用进行数据交互)问题:我们的上游有另一个组件C(带有界面),调用A(us)进行数据的变更操作,此时需要A调用B服务接口进行同步,问题出在这里,C调用A通常速度比较快,比较稳定,但是A调用B经常超时或者失败,网络原因or 组件B自己的设计原因吧,反正是推不动方案:经沟通考察,这条数据的变更...

weixin_39959335的博客 854

GO与KEGG富集分析实战:从差异基因到功能注释

本文详细介绍了GO与KEGG富集分析的完整实战流程,从差异基因列表出发,通过基因ID转换、核心分析到结果可视化,系统阐述了如何将基因数据转化为生物学洞察。文章重点讲解了使用R语言clusterProfiler包进行GO和KEGG富集分析的具体步骤、参数设置及常见问题解决方案,并强调了结果解读与生物学故事构建的方法,帮助研究者深入理解差异基因的集体功能倾向。

weixin_29291863的博客 920

双屏DPI缩放问题全解析:从原理到实战解决窗口大小突变

DPI(每英寸点数)缩放是现代操作系统在多显示器环境下实现界面适配的核心技术。其原理是通过虚拟分辨率映射,在不同物理像素密度的屏幕上维持一致的视觉尺寸。这项技术的价值在于解决了高分辨率屏幕显示内容过小的问题,保障了跨屏工作流的视觉连续性。然而,在混合DPI环境(如4K屏与1080p屏组合)中,显卡驱动逻辑与应用程序DPI感知的协同问题,常导致窗口跨屏时出现剧烈缩放、尺寸错乱。这直接影响多屏办公、设计协作等需要频繁拖拽窗口的应用场景。本文聚焦于**显卡驱动**配置与**应用程序兼容性**设置,提供一套从系统底

weixin_34364071的博客 388

seata xid是什么_分布式事务原理分析及SpringBoot整合RabbitMQ实现可靠事件,TCC补偿事务模型及什么是接口幂等性...

分布式事务在单数据库系统中,实现数据的一致性,通过数据库的事务来处理比较简单。在微服务或分布式系统中,各个独立的服务都会有自己的数据库,而不是在同一个数据库中,所以当一组事务(如商品交易中,商品的库存、用户的账户资金和交易记录等)的处理是分布在不同数据库中的,分布式事务就是为了解决在多个数据库节点中保证这些数据的一致性。分布式事务里有个BASE理论,在分布式数据库中,存在强一致性和弱一致...

weixin_29876033的博客 435

【NodeRed】node-red-contrib-opcua实现PLC读写

在之前的博文【Node-RED】node-red-contrib-opcua-server模块使用(1)中,我们介绍了用node-red-contrib-opcua-server模块实现OPCUA服务端的,以及二次开发的内容。本节博文中我们采用官方社区自带的node-red-contrib-opcua组件开展对OPCUA客户端的介绍,详细阐述用该组件中OpcUa-Client节点实现客户端对PLC的读写,以及实现过程中遇到的问题。由于官方社区中并没有找到该组件的介绍实例,这也是本博文编写的第1个原因。

weixin_48618536的博客 960

[java][事务]tcc事务实战学习过程

学习项目:https://github.com/14251104246/spring-cloud-rest-tcc 下载源码,进入源码目录运行:mvn clean package Docker Compose运行 docker-compose -f infrastructure-compose.yml up -d docker-compose -f basic-ms-compose.yml u...

qq523786283的博客 1613

下载MNIST数据集并使用python将数据转换成NumPy数组(源码解析)

下载MNIST数据集并使用python将数据转换成NumPy数组首先来分析init_mnist函数接下来继续分析load_mnist函数实现数据集转换的python脚本的代码显示MNIST图像并确认数据 下载MNIST数据集并将数据转换成NumPy数组的Python脚本里面最重要的就是load_mnist函数,其他项目想要调用数据集的话,就可以调用load_mnist函数,得到一个字典类型的数据,字典的值是一个Numpy数组。 这些过程是如何实现的,现在开始逐字逐句分析源码: 在load_mnist函数中第

及时总结 4268

C# NX二次开发-查找连续倒圆角面

可以通过ufun函数 UF_MODL_ask_face_type 和 UF_MODL_ask_face_props 可判断处理选择相应的一组圆角面。在QQ群里有人问怎么通过一个选择一个倒圆角面来自动选中一组倒圆角面。这个是初步思路,如果有更好的思路可回复讨论一下。

fhqiwmc的博客 621

微服务下的数据一致性的几种实现方式

目录 1. 传统应用的事务管理 1.1 本地事务 1.2 分布式事务 2. 微服务下的事务管理 3. 实现微服务下数据一致性的方式 3.1 可靠事件通知模式 3.2 最大努力通知模式 3.3 业务补偿模式 3.4 TCC/Try Confirm Cancel模式 3.5 总结 1. 传统应用的事务管理 1.1 本地事务 再介绍微服务下的数据一致性之前,先简单地介绍一...

延宝小白马的博客 7452

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Spring Boot面试题大揭秘:3个必问问题+答案解析,面试官都惊呆了!

Spring Boot作为Java开发的核心框架,面试中经常考察其实际应用能力。掌握配置管理、服务通信和分布式事务处理,能让你在面试中脱颖而出。建议结合实际项目经验,深入理解这些技术的实现原理和适用场景。

weixin_45706752的博客 799

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

理论系列-分布式服务架构笔记

理论系列-分布式服务架构笔记 1. 前言 1.1 发展 - - 1 传统单体架构 2 服务化架构(SOA) 3 微服务 4 容器化 5 云原生 传统单体架构:分层(应用层,服务层,存储层) 服务化架构:服务组件(基于网络通信对外提供服务) 实现一:Web Service 实现二:ESB 微服务架构:微小服务(通常用RESTful风格API通信) 1.2 RPC框架 - - JDK RMI Hessian Spring HTTP Invoke

xl十一的博客 140

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

大厂Java面试核心:Spring原理与微服务架构解析

Java作为企业级开发的主流语言,其技术栈深度与架构能力是面试的核心考察点。从JVM内存模型到Spring框架的IOC容器实现,技术原理的理解直接影响系统性能与稳定性。微服务架构下,服务注册发现机制与分布式事务解决方案成为关键技术,如Nacos的多协议支持和SAGA模式的应用。结合Redis缓存优化与MySQL索引原理,这些技术共同构建高并发系统的基石。本文通过三级缓存解决循环依赖等典型案例,揭示大厂面试对技术深度的考察逻辑,为开发者提供从基础到架构的系统性准备方案。

weixin_34208185的博客 344

Java技术面试实战:从Spring Boot到微服务架构(附详细答案解析)

Spring Boot的核心特性包括自动配置、嵌入式服务器(如Tomcat)、starter依赖管理等,帮助开发者快速构建独立运行的应用程序。:Spring Boot是一个快速开发框架,它简化了Spring应用的配置,提供了自动配置功能。:可以使用两阶段提交协议,或者采用补偿机制,比如TCC(Try-Confirm-Cancel)模式。可以在底层实现分页,但更推荐使用PageHelper插件,因为它支持更多复杂的分页场景……:Spark适合批处理,Flink更适合实时流处理,Flink的延迟更低。

m0_62758843的博客 1761

Java大厂面试技术栈解析:Spring Boot与微服务实战

Java技术栈在现代互联网企业中占据核心地位,尤其在电商等高并发场景下,其性能优化和架构设计尤为重要。从基础原理来看,Java 8的Lambda表达式和Stream API通过并行处理大幅提升数据处理效率,而Spring Boot则简化了企业级应用的开发流程。这些技术的价值在于能够构建高性能、可扩展的分布式系统,广泛应用于订单处理、库存管理等核心业务场景。本文结合美团和阿里实战经验,深入解析Spring Boot、微服务架构及AI集成等关键技术,涵盖并行流优化、RESTful服务构建、分布式事务方案等实用内

weixin_30889885的博客 363

SpringBoot汽车票系统架构设计与高并发实践

微服务架构是现代分布式系统的主流设计模式,通过将单体应用拆分为独立部署的服务单元,显著提升了系统的可扩展性和容错能力。SpringBoot作为微服务开发的利器,其自动配置特性和丰富的Starter依赖大幅降低了开发复杂度。在票务系统这类高并发场景中,需要特别关注缓存策略和数据库优化,例如采用Redis实现多级缓存、MySQL读写分离等技术手段。本文以汽车票预订系统为例,详细解析了如何基于SpringBoot+Redis+MySQL技术栈应对秒杀场景、保证分布式事务一致性,并分享了容器化部署和CI/CD实践中

weixin_30345577的博客 396
上一篇: 分布式事务的典型处理方式:2PC、TCC、异步确保和最大努力型
下一篇: Jsoup 解析 HTML
hxpjava1
博客等级 码龄19年 1365粉丝 511原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值