《微服务实战》 第三十章 分布式事务框架seata TCC模式

news2024/11/19 14:54:13

前言

本章节介绍分布式事务框架seata TCC模式,上一章节介绍seata以及集成到Springboot、微服务框架里。

1、TCC模式

一个分布式的全局事务,整体是 两阶段提交 的模型。全局事务是由若干分支事务组成的,分支事务要满足 两阶段提交 的模型要求,即需要每个分支事务都具备自己的:

  • 一阶段 prepare 行为
  • 二阶段 commit 或 rollback 行为
    在这里插入图片描述

根据两阶段行为模式的不同,我们将分支事务划分为 Automatic (Branch) Transaction Mode 和 TCC (Branch) Transaction Mode.

1.1、AT 模式(参考链接 TBD)基于 支持本地 ACID 事务 的 关系型数据库

1.1.1、 一阶段 prepare 行为

在本地事务中,一并提交业务数据更新和相应回滚日志记录。

1.1.2、二阶段 commit 行为

马上成功结束,自动 异步批量清理回滚日志。

1.1.3、二阶段 rollback 行为

通过回滚日志,自动 生成补偿操作,完成数据回滚。

1.2、TCC 模式,不依赖于底层数据资源的事务支持

1.2.1、一阶段 prepare 行为

调用 自定义 的 prepare 逻辑。try

1.2.2、二阶段 commit 行为

调用 自定义 的 commit 逻辑。confirm

1.2.3、二阶段 rollback 行为

调用 自定义 的 rollback 逻辑。cancel

2、例子

2.1、定义controller

/**
 * 采购
 */
@PostMapping("/purchaseTCC")
@GlobalTransactional
public String purchaseTCC(@RequestBody OrderDTO orderDTO){
    this.businessTCCService.purchase(orderDTO);
    return "success";
}

2.2、定义service

@LocalTCC
public interface BusinessTCCService {
    /**
     * 采购 执行资源检查及预留操作
     */
    @TwoPhaseBusinessAction(name = "purchase",commitMethod = "commit",rollbackMethod = "rollback")
    public void purchase(@BusinessActionContextParameter(paramName = "orderDTO") OrderDTO orderDTO);

    /**
     * 全局事务进行提交
     * @param businessActionContext
     * @return
     */
    boolean commit(BusinessActionContext businessActionContext);

    /**
     * 全局事务进行不回滚
     * @param businessActionContext
     * @return
     */
    boolean rollback(BusinessActionContext businessActionContext);
}

package com.xxxx.store.business.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xxxx.store.business.service.BusinessService;
import com.xxxx.store.business.service.BusinessTCCService;
import com.xxxx.store.business.service.OrderService;
import com.xxxx.store.business.service.StorageService;
import com.xxxx.store.common.dto.OrderDTO;
import com.xxxx.store.common.dto.StorageDTO;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;

@Service
public class BusinessTCCServiceImpl implements BusinessTCCService {
    @Value("${file.path}")
    private String filePath;
    @Autowired
    private OrderService orderService;
    @Autowired
    private StorageService storageService;

    @Override
    public void purchase(OrderDTO orderDTO) {
        //减库存
        this.storageService.deduct(new StorageDTO(null,orderDTO.getCommodityCode(),orderDTO.getCount()));
        //创建订单
        this.orderService.create(orderDTO);
    }

    @Override
    public boolean commit(BusinessActionContext businessActionContext) {
        System.out.println("事务ID:" + businessActionContext.getXid());
        return true;
    }

    @Override
    public boolean rollback(BusinessActionContext businessActionContext) {
        JSONObject jSONObject = (JSONObject)businessActionContext.getActionContext("orderDTO");

        OrderDTO orderDTO = jSONObject.toJavaObject(OrderDTO.class);
        StorageDTO storageDTO = new StorageDTO(null, orderDTO.getCommodityCode(), orderDTO.getCount());

        String s = JSON.toJSONString(storageDTO);
        String md5 = SecureUtil.md5(s);
        System.out.println("**************触发回滚操作:" + filePath + md5);
        File file = new File(filePath + md5);
        file.delete();
        return true;
    }

    /*@Override
    public void purchase(OrderDTO orderDTO) {
        //减库存
        this.storageService.deduct(new StorageDTO(null,orderDTO.getCommodityCode(),orderDTO.getCount()));
        //创建订单
        this.orderService.create(orderDTO);
    }*/

}
注解描述
@LocalTCC一定需要注解在接口上,否则不生效,此接口可以是寻常的业务接口,只要实现了TCC的两阶段提交对应方法便可,适用于SpringCloud+Feign模式下的TCC。
@TwoPhaseBusinessAction注解try方法,其中name为当前tcc方法的bean名称,写方法名便可(全局唯一),commitMethod指向提交方法,rollbackMethod指向事务回滚方法。指定好三个方法之后,seata会根据全局事务的成功或失败,自动调用提交方法或者回滚方法。
@BusinessActionContextParameter使用该注解可以将参数传递到二阶段commit或者rollback的方法中,方便调用。
BusinessActionContextTCC事务上下文,使用BusinessActionContext.getActionContext(“params”)便可以得到一阶段try中定义的参数,在二阶段参考此参数进行业务回滚操作。

建议:可以在try方法中使用@Transational,直接通过spring来控制关系型数据库的事务,进行回滚的操作,而非关系型数据库等中间件的回滚操作可以交给rollbackMethod方法处理。

建议:try接口不可以捕获异常,否则TCC将识别该操作为成功,直接执行二阶段commit方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/633456.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何利用ChatGPT写毕业论文

如何利用ChatGPT写毕业论文 ChatGPT是什么?利用ChatGPT写毕业论文的步骤1.准备数据2.训练模型3.生成论文4.检查论文 总结地址 ChatGPT是什么? ChatGPT是一个基于GPT-2模型的开源聊天机器人,它可以回答用户的问题,进行闲聊和提供各…

或许是一个新的算法方向?

动动发财的小手,点个赞吧! 今日谷歌 DeepMind 使用深度强化学习发现更快的排序算法,相关论文[1]成果已经发表在Nature上。 据报道:该算法可以提速 70%,相比之下,快了3倍之多。 摘要 排序或散列等…

230611-通过Doxygen实现项目代码的文档自动化生成(Mac+Win通用)

背景介绍 目前主流的Python项目的文档管理多通过Sphinx实现;当前Sphinx尚未有针对C#等代码的插件;若想对C#的项目代码进行Sphinx的管理,可通过Doxygen导出为xml文件,进行二次转换;有关Doxygen的介绍及使用&#xff0c…

Java使用Opencv进行大图找小图并使用其找图功能进行bilibili视频下载案例

Java使用Opencv进行大图找小图并使用其找图功能进行bilibili视频下载案例 一、Opencv大图找小图说明二、Opencv的window安装1.下载windows下的安装包2.安装3.Java中Opencv加载测试 三、Java中通过Opencv进行模板匹配大图找小图四、进行多图查找五:案例下载bilibili视…

碳排放预测模型 | Python实现基于机器学习回归分析的碳排放预测模型——随机森林、决策树、KNN 和多层感知器 (MLP) 预测分析

文章目录 效果一览文章概述研究内容环境准备源码设计KNNRandom ForestDecision TreeMLPModel Evaluation学习总结参考资料效果一览

【Android开发基础】随机点名系统(关于读取xml资源文件)

文章目录 一、引言二、设计1、读取xml2、下拉框Spinner3、随机算法 三、实施1、子元素随机(单位:班级)2、父元素随机(单位:专业)3、指定人数随机4、指定人数混合排序 四、附件 一、引言 描述:这…

【手撕MyBatis源码】动态SQL全流程解析

文章目录 动态SQL概述ifchoose(when、otherwise)trim(where、set)foreach OGNL表达式BoundSql动态SQL主流程分析SqlNodeDynamicContext源码解析StaticTextSqlNodeTextSqlNodeIfSqlNodeChooseSqlNodeForEachSqlNode 动态脚本结构动态脚本执行 SqlSourceSt…

Spring Cloud - Eureka原理、注册、搭建、应用(全过程详解)

目录 一、Eureka 注册原理 1.1、为什么要使用 Eureka 1.2、Eureka 的工作流程及原理 1.3、eureka 的作用 二、具体实现 2.1、搭建注册中心 2.2、服务注册和部署 2.2.1、user-service 服务注册 2.2.2、服务部署 2.2.3、order-service 服务注册 2.2.4、验证服务 2.3、…

java SSM 药品集中管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 药品集中管理系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代 码和数据库,系统主要采…

[神经网络]迁移学习-微调

一、概述 一般的有监督迁移学习分为以下三种: ①将训练好的模型作为特征抽取模块(例如以resnet进行特征提取) ②在一个相关的任务中训练后直接后直接使用(例如gpt) ③在训练好的模型基础上进行微调 此外还有无监督学习的方式 zero-shot&#…

【集群】LVS+Keepalived群集

文章目录 前言一、Keepalived的概念1. Keepalived 概述2. Keepalived 作用3. Keepalived 实现原理剖析3.1 Keepalived 工作原理3.1 VRRP协议(虚拟路由冗余协议) 4. Keepalived 主要模块及其作用4.1 健康检查方式(学名:探针&#x…

【架构基础】正交设计四原则

数学中的正交,是指相互垂直的两个向量,简单来讲就是平面上的两个垂直线段,其中一个线段变长或减短或者转圈圈,另外一根是不变的也不影响它们的垂直度的。表现为空间的独立性,在软件中我们可以理解为两个只有交叉点而互…

springboot0+java+vuie个人家庭财务理财系统

。本文介绍了个人理财系统的开发全过程。通过分析个人理财系统管理的不足,创建了一个计算机管理个人理财系统的方案。文章介绍了个人理财系统的系统分析部分,包括可行性分析等,系统设计部分主要介绍了系统功能设计和数据库设计。 本个人理财系…

【数据湖架构】在 Azure Data Lake Storage (ADLS)二代上构建数据湖

介绍 一开始,规划数据湖似乎是一项艰巨的任务——决定如何最好地构建数据湖、选择哪种文件格式、是拥有多个数据湖还是只有一个数据湖、如何保护和管理数据湖。并非所有这些都需要在第一天回答,有些可能通过反复试验来确定。构建数据湖没有明确的指南&am…

【C++】一文带你吃透C++多态

🍎 博客主页:🌙披星戴月的贾维斯 🍎 欢迎关注:👍点赞🍃收藏🔥留言 🍇系列专栏:🌙 C/C专栏 🌙那些看似波澜不惊的日复一日,…

【链表part02】| 24.两两交换链表中的节点、19.删除链表的倒数第N个节点、02.07.链表相交、142.环形链表

目录 ✿LeetCode24.两两交换链表中的节点❀ ✿LeetCode19.删除链表的倒数第N个节点❀ ✿LeetCode面试题 02.07. 链表相交❀ ✿LeetCode142.环形链表||❀ ✿LeetCode24.两两交换链表中的节点❀ 链接:24.两两交换链表中的节点 给你一个链表,两两交换其…

轻骑逐单于,大雪满弓刀:华为分布式存储的一骑绝尘

唐代诗人卢纶,有一首脍炙人口的《和张仆射塞下曲》,“月黑雁飞高,单于夜遁逃。欲将轻骑逐,大雪满弓刀。”诗中的慷慨激昂,热血炙烈,千年来让无数国人心魂激荡。 时代变迁,岁月迁移,今…

LeetCode面向运气之Javascript—第20题-有效的括号-95.97%

LeetCode第20题-有效的括号 题目要求 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。左括号…

卑微小测试的一天----自动生成正交法测试用例

前言 工作过程中,我们接触到需求后第一要务是 熟悉需求并且输出测试用例,针对接口测试的入参测试,需要校验大量入参的组合场景,这时我们通常采用正交法来设计测试用例,在减少测试用例的数量时,同时保障测试…

Java 命名规范

包命名规范 包(Package) 的作用是将功能相似或相关的类或者接口进行分组管理,便于类的定位和查找,同时也可以使用包来避免类名的冲突和访问控制,使代码更容易维护。通常,包名使用小写英文字母进行命名,并使用 “.” 进…