百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

用Java轻松完成一个分布式事务TCC,保姆级教程

ccwgpt 2024-09-26 07:51 37 浏览 0 评论

TCC 组成

TCC 分为 3 个阶段

Try 阶段:尝试执行,完成所有业务检查(一致性), 预留必须业务资源(准隔离性)

Confirm 阶段:如果所有分支的 Try 都成功了,则走到 Confirm 阶段。Confirm 真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源

Cancel 阶段:如果所有分支的 Try 有一个失败了,则走到 Cancel 阶段。Cancel 释放 Try 阶段预留的业务资源。

TCC 分布式事务里,有 3 个角色,与经典的 XA 分布式事务一样:

AP / 应用程序,发起全局事务,定义全局事务包含哪些事务分支

RM / 资源管理器,负责分支事务各项资源的管理

TM / 事务管理器,负责协调全局事务的正确执行,包括 Confirm,Cancel 的执行,并处理网络异常

如果我们要进行一个类似于银行跨行转账的业务,转出(TransOut)和转入(TransIn)分别在不同的微服务里,一个成功完成的 TCC 事务典型的时序图如下:

TCC 实践

下面我们进行一个 TCC 事务的具体开发

我们的例子使用的分布式事务框架为 dtm,它对分布式事务的支持非常优雅。下面来详细讲解 TCC 的组成

下面我们来编写具体的 Try/Confirm/Cancel 的处理函数

@RequestMapping("TransOutTry")
    public Map<String, String> TransOutTry() {
        logger.info("TransOutTry");
        Map<String, String> result = new HashMap<>();
        result.put("dtm_result", "SUCCESS");
        return result;
    }

    @RequestMapping("TransOutConfirm")
    public Map<String, String> TransOutConfirm(HttpServerResponse response) {
        logger.info("TransOutConfirm");
        Map<String, String> result = new HashMap<>();
        result.put("dtm_result", "SUCCESS");
        return result;
    }

    @RequestMapping("TransOutCancel")
    public Map<String, String> TransOutCancel() {
        logger.info("TransOutCancel");
        Map<String, String> result = new HashMap<>();
        result.put("dtm_result", "SUCCESS");
        return result;
    }

    @RequestMapping("TransInTry")
    public Map<String, String> TransInTry() {
        logger.info("TransInTry");
        Map<String, String> result = new HashMap<>();
        result.put("dtm_result", "SUCCESS");
        return result;
    }

    @RequestMapping("TransInConfirm")
    public Map<String, String> TransInConfirm() {
        logger.info("TransInConfirm");
        Map<String, String> result = new HashMap<>();
        result.put("dtm_result", "SUCCESS");
        return result;
    }

    @RequestMapping("TransInCancel")
    public Map<String, String> TransInCancel() {
        logger.info("TransInCancel");
        Map<String, String> result = new HashMap<>();
        result.put("dtm_result", "SUCCESS");
        return result;
    }

到此各个子事务的处理函数已经 OK 了,然后是开启 TCC 事务,进行分支调用

   @RequestMapping("fireTcc")
    public String fireTcc() {
        Function<Tcc, Boolean> function = TccController::tccTrans;
        return tcc.tccGlobalTransaction(function);
    }

    public static Boolean tccTrans(Tcc tcc) {
        try {
            boolean a = tcc.callBranch("", svc + "/TransOutTry", svc + "/TransOutConfirm", svc + "/TransOutCancel");
            boolean b = tcc.callBranch("", svc + "/TransInTry", svc + "/TransInConfirm", svc + "/TransInCancel");
            return a && b;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

至此,一个完整的 TCC 分布式事务编写完成。

如果您想要完整运行一个成功的示例,那么参考这个例子 yedf/dtmcli-java-sample,将它运行起来非常简单

# 部署启动dtm
# 需要docker版本18以上
git clone https://github.com/yedf/dtm
cd dtm
docker-compose up

# 另起一个命令行
git clone https://github.com/yedf/dtmcli-java-sample.git
cd dtmcli-java-sample
# 编译运行例子 main/src/main/java/com/github/viticis/dtmclijavaexamples/DtmcliJavaSampleApplication

TCC 的回滚

假如银行将金额准备转入用户 2 时,发现用户 2 的账户异常,返回失败,会怎么样?我们可以让 TransIn 返回失败来模拟这种情况

   @RequestMapping("TransInTry")
    public Map<String, String> TransInTry() {
        logger.info("TransInTry");
        Map<String, String> result = new HashMap<>();
        result.put("dtm_result", "FAILURE");
        return result;
    }

我们给出事务失败交互的时序图

这个跟成功的 TCC 差别就在于,当某个子事务返回失败后,后续就回滚全局事务,调用各个子事务的 Cancel 操作,保证全局事务全部回滚。

在 TCC 事务模式上,有不少的读者会问,如果 Confirm/Cancel 失败会怎么样?这是一个好问题,代表您正在深入思考 TCC 事务模式。第一种情况是临时失败,例如网络故障、应用或数据库宕机,这类错误进行重试,最后会返回成功;另一种情况为业务失败,按照 TCC 的协议,第一阶段锁定资源,保证足够的资源能够让 Confirm/Cancel 执行,也就是说,程序逻辑上,Confirm/Cancel 是不允许返回业务失败的,如果出现业务失败,那么是 bug,需要开发人员手动修复 bug。

原文作者:dongfuye

转自链接:https://learnku.com/articles/61324

相关推荐

用Deepseek扩写土木工程毕业论文实操指南

用Deepseek扩写毕业论文实操指南一、前期准备整理现有论文初稿/提纲列清楚论文核心框架(背景、现状、意义、方法、数据、结论等)梳理好关键文献,明确核心技术路线二、Deepseek扩写核心思路...

985学霸亲授,DeepSeek也能绘6大科研图表,5分钟就出图

在实验数据处理中,高效可视化是每个科研人的必修课。传统绘图软件操作复杂、耗时费力,而智能工具DeepSeek的出现彻底改变了这一现状。本文将详解如何用DeepSeek一键生成六大科研常用图表,从思维导...

AI写论文刷屏?大学生正在丢掉的思考力

一、宿舍深夜:当论文变成"Ctrl+C+V"凌晨两点的大学宿舍,小王对着电脑屏幕叹气。本该三天前开始写的近代史论文,此刻还一片空白。他熟练打开某AI写作网站,输入"论五四运动的...

Grok在辅助论文写作上能不能既“聪明”又“可怕”?!

AcademicIdeas-学境思源AI初稿写作随着人工智能技术的飞速发展,论文写作这一学术任务正迎来新的助力。2025年2月18日,美国xAI公司推出了备受瞩目的Grok3模型,其创始人埃隆·...

大四论文沟通场景!音频转文字难题听脑AI来化解

大四学生都知道,写论文时和导师沟通修改意见,简直是“过关斩将”。电话、语音沟通完,想把导师说的修改方向、重点要求记下来,麻烦事儿可不少。手写记不全,用普通录音转文字工具,转完还得自己慢慢找重点,稍不注...

论文写作 | 技术路线图怎么画?(提供经典优秀模板参考)

技术路线图是一种图表或文字说明,用于描述研究目标、方法和实施计划。它展示了研究的整体框架和步骤,有助于读者理解研究的逻辑和进展。在课题及论文中,技术路线图是常见的一部分,甚至是一个类似心脏一样的中枢器...

25年信息系统项目管理师考试第2批论文题目写作建议思路框架

25年信息系统项目管理师考试第2批论文题目写作建议思路框架--马军老师

微信购物应尽快纳入法律框架(微信购物管辖)

符向军近日,甘肃省工商行政管理局发布《2016年上半年信息分析报告》。报告显示,微信网购纠纷迅猛增长,网络购物投诉呈上升趋势。投诉的主要问题有出售的商品质量不过关、消费者通过微信付款后对方不发货、购买...

泛珠三角区域网络媒体与腾讯微信签署《战略合作框架协议》

新海南客户端、南海网7月14日消息(记者任桐)7月14日上午,参加第四届泛珠三角区域合作网络媒体论坛的区域网络媒体负责人及嘉宾一行到腾讯微信总部座谈交流,并签署《战略合作框架协议》(以下简称《框架协...

离线使用、植入微信-看乐心Mambo手环如何打破框架

从2014年开始智能手环就成功进入人们的生活,至今已经演变出数据监测、信息推送、心率监测等诸多五花八门的功能,人们选择智能手环并不指望其能够改变身体健康情况,更多的是通过数据来正视自身运动情况和身体健...

微信私域电商运营策略与框架(微信私域怎么做)

...

华专网络:如何零基础制作一个网站出来?

#如何零基础制作一个网站出来?#你是不是觉得网站建设很复杂,觉得自己是小白,需求不明确、流程搞不懂、怕被外包公司坑……这些问题我都懂!今天华专网络就用大白话给你捋清楚建站的全流程,让你轻松get网站制...

WAIC2024丨明日上午9点,不见不散!共同探讨智能社会与全球治理框架

大咖云集,硕果闪耀WAIC2024世界人工智能大会智能社会论坛将于7月5日9:00-12:00与你相约直播间WAIC2024上海杨浦同济大学哔哩哔哩多平台同步直播探讨智能社会与全球治理框架WAIC...

约基奇:森林狼换来戈贝尔时大家都在嘲笑 他们的阵容框架很不错

直播吧5月4日讯西部季后赛半决赛,掘金将迎战森林狼,约基奇赛前接受采访。约基奇说道:“当蒂姆-康纳利(森林狼总经理、前掘金总经理&曾选中约基奇)做了那笔交易(换来戈贝尔)时,每个人都在嘲笑他...

视频号带货为什么一个流量都没有?顶级分析框架送给你

视频号带货为什么一个流量都没有?遇到问题,一定是步步来分析内容,视频号带货一个流量都没有,用另外一个意思来讲,就可以说是零播放。为什么视频号带货一个流量都没有?跟你说再多,都不如来个分析框架。1、是否...

取消回复欢迎 发表评论: