SSM 如何使用 TCC 机制实现分布式事务?
SSM 如何使用 TCC 机制实现分布式事务?
分布式事务是现代分布式系统中必不可少的一部分,而 TCC 机制(Try-Confirm-Cancel)是一种常用的分布式事务处理方式。在 SSM 框架中,我们可以使用 TCC 机制来管理分布式事务。本文将介绍如何在 SSM 框架中使用 TCC 机制实现分布式事务,并提供相应的代码示例。

什么是 TCC 机制?
TCC 机制是一种分布式事务处理方式,其核心思想是将一个分布式事务拆分成三个阶段:Try、Confirm 和 Cancel。具体来说,TCC 机制将一个分布式事务拆分成以下三个步骤:
- Try 阶段:在该阶段中,系统会尝试执行分布式事务。如果所有的业务操作都执行成功,则分布式事务进入 Confirm 阶段。如果任何一个业务操作执行失败,则分布式事务进入 Cancel 阶段。
- Confirm 阶段:在该阶段中,系统会确认执行所有业务操作。如果所有业务操作都执行成功,则分布式事务提交。如果任何一个业务操作执行失败,则分布式事务回滚。
- Cancel 阶段:在该阶段中,系统会撤销所有业务操作。如果所有业务操作都成功撤销,则分布式事务回滚完成。如果任何一个业务操作无法撤销,则分布式事务无法回滚。
通过 TCC 机制,我们可以对分布式事务进行更加细粒度的控制,从而降低系统出错的概率。
SSM 中如何使用 TCC 机制实现分布式事务?
在 SSM 框架中,我们可以使用 TCC 机制来管理分布式事务。具体来说,我们可以通过 Spring 的声明式事务管理和 Dubbo 的分布式事务管理来实现 TCC 机制。
Spring 的声明式事务管理
在 Spring 的声明式事务管理中,我们可以使用 @Transactional 注解来实现 TCC 机制。具体来说,我们可以将一个分布式事务拆分成以下三个方法:
- Try 方法:在该方法中,我们会执行所有的业务操作,并将操作结果保存到一个全局事务上下文对象中。
- Confirm 方法:在该方法中,我们会确认所有的业务操作。如果所有业务操作都执行成功,则会将全局事务上下文对象中的操作结果提交。如果任何一个业务操作执行失败,则会将全局事务上下文对象中的操作结果回滚。
- Cancel 方法:在该方法中,我们会撤销所有的业务操作。如果所有业务操作都成功撤销,则会将全局事务上下文对象中的操作结果回滚。如果任何一个业务操作无法撤销,则会将全局事务上下文对象中的操作结果置为“未知”状态。
下面是一个使用 Spring 的声明式事务管理实现 TCC 机制的示例代码:
@Service
public class TccService {@Autowiredprivate TccDao tccDao;@Autowiredprivate GlobalTransactionContext globalTransactionContext;@Transactionalpublic void tryMethod() {// 执行业务操作1boolean result1 = tccDao.doSomething1();// 执行业务操作2boolean result2 = tccDao.doSomething2();// 将操作结果保存到全局事务上下文对象中globalTransactionContext.addResult("result1", result1);globalTransactionContext.addResult("result2", result2);}@Transactionalpublic void confirmMethod() {// 确认业务操作1boolean result1 = globalTransactionContext.getResult("result1");if (result1) {tccDao.confirmSomething1();}// 确认业务操作2boolean result2 = globalTransactionContext.getResult("result2");if (result2) {tccDao.confirmSomething2();}// 提交分布式事务globalTransactionContext.commit();}@Transactionalpublic void cancelMethod() {// 撤销业务操作1boolean result1 = globalTransactionContext.getResult("result1");if (result1) {tccDao.cancelSomething1();}// 撤销业务操作2boolean result2 = globalTransactionContext.getResult("result2");if (result2) {tccDao.cancelSomething2();}// 回滚分布式事务globalTransactionContext.rollback();}
}
在上面的代码中,我们定义了一个 TccService 类,并使用 @Transactional 注解将 tryMethod()、confirmMethod() 和 cancelMethod() 方法标记为需要参与分布式事务的方法。在 tryMethod() 方法中,我们执行了所有的业务操作,并将操作结果保存到全局事务上下文对象中。在 confirmMethod() 方法中,我们通过全局事务上下文对象获取所有的业务操作结果,并根据结果确认或回滚业务操作。在 cancelMethod() 方法中,我们通过全局事务上下文对象获取所有的业务操作结果,并根据结果撤销业务操作。
Dubbo 的分布式事务管理
在 Dubbo 的分布式事务管理中,我们可以使用 @Compensable 注解来实现 TCC 机制。具体来说,我们可以将一个分布式事务拆分成以下三个方法:
- Try 方法:在该方法中,我们会执行所有的业务操作,并将操作结果保存到一个全局事务上下文对象中。
- Confirm 方法:在该方法中,我们会确认所有的业务操作。如果所有业务操作都执行成功,则会将全局事务上下文对象中的操作结果提交。如果任何一个业务操作执行失败,则会将全局事务上下文对象中的操作结果回滚。
- Cancel 方法:在该方法中,我们会撤销所有的业务操作。如果所有业务操作都成功撤销,则会将全局事务上下文对象中的操作结果回滚。如果任何一个业务操作无法撤销,则会将全局事务上下文对象中的操作结果置为“未知”状态。
下面是一个使用 Dubbo 的分布式事务管理实现 TCC 机制的示例代码:
@Service
public class TccService {@Autowiredprivate TccDao tccDao;@Autowiredprivate GlobalTransactionContext globalTransactionContext;@Compensable(confirmMethod = "confirmMethod", cancelMethod = "cancelMethod")public void tryMethod() {// 执行业务操作1boolean result1 = tccDao.doSomething1();// 执行业务操作2boolean result2 = tccDao.doSomething2();// 将操作结果保存到全局事务上下文对象中globalTransactionContext.addResult("result1", result1);globalTransactionContext.addResult("result2", result2);}public void confirmMethod() {// 确认业务操作1boolean result1 = globalTransactionContext.getResult("result1");if (result1) {tccDao.confirmSomething1();}// 确认业务操作2boolean result2 = globalTransactionContext.getResult("result2");if (result2) {tccDao.confirmSomething2();}// 提交分布式事务globalTransactionContext.commit();}public void cancelMethod() {// 撤销业务操作1boolean result1 = globalTransactionContext.getResult("result1");if (result1) {tccDao.cancelSomething1();}// 撤销业务操作2boolean result2 = globalTransactionContext.getResult("result2");if (result2) {tccDao.cancelSomething2();}// 回滚分布式事务globalTransactionContext.rollback();}
}
在上面的代码中,我们定义了一个 TccService 类,并使用 @Compensable 注解将 tryMethod() 方法标记为需要参与分布式事务的方法。在 tryMethod() 方法中,我们执行了所有的业务操作,并将操作结果保存到全局事务上下文对象中。在 confirmMethod() 方法中,我们通过全局事务上下文对象获取所有的业务操作结果,并根据结果确认或回滚业务操作。在 cancelMethod() 方法中,我们通过全局事务上下文对象获取所有的业务操作结果,并根据结果撤销业务操作。
需要注意的是,在 Dubbo 的分布式事务管理中,我们需要使用一个全局事务上下文对象来保存所有的业务操作结果。在上面的示例代码中,我们通过 @Autowired 注解注入了一个 GlobalTransactionContext 对象,用于保存所有的业务操作结果。在实际应用中,我们可以使用 Redis、Zookeeper 等分布式存储系统来实现全局事务上下文对象。
总结
在本文中,我们介绍了如何在 SSM 框架中使用 TCC 机制实现分布式事务。具体来说,我们可以通过 Spring 的声明式事务管理和 Dubbo 的分布式事务管理来实现 TCC 机制。通过 TCC 机制,我们可以对分布式事务进行更加细粒度的控制,从而降低系统出错的概率。在实际应用中,我们需要根据业务场景选择合适的分布式事务处理方式,并根据实际情况进行优化和调整,以提高系统的可靠性和性能。
附:完整代码示例
Dao 层
@Repository
public class TccDao {public boolean doSomething1() {// 执行业务操作1return true;}public void confirmSomething1() {// 确认业务操作1}public void cancelSomething1() {// 撤销业务操作1}public boolean doSomething2() {// 执行业务操作2return true;}public void confirmSomething2() {// 确认业务操作2}public void cancelSomething2() {// 撤销业务操作2}
}
Service 层
@Service
public class TccService {@Autowiredprivate TccDao tccDao;@Autowiredprivate GlobalTransactionContext globalTransactionContext;@Transactionalpublic void tryMethod() {//执行业务操作1boolean result1 = tccDao.doSomething1();// 执行业务操作2boolean result2 = tccDao.doSomething2();// 将操作结果保存到全局事务上下文对象中globalTransactionContext.addResult("result1", result1);globalTransactionContext.addResult("result2", result2);}@Transactionalpublic void confirmMethod() {// 确认业务操作1boolean result1 = globalTransactionContext.getResult("result1");if (result1) {tccDao.confirmSomething1();}// 确认业务操作2boolean result2 = globalTransactionContext.getResult("result2");if (result2) {tccDao.confirmSomething2();}// 提交分布式事务globalTransactionContext.commit();}@Transactionalpublic void cancelMethod() {// 撤销业务操作1boolean result1 = globalTransactionContext.getResult("result1");if (result1) {tccDao.cancelSomething1();}// 撤销业务操作2boolean result2 = globalTransactionContext.getResult("result2");if (result2) {tccDao.cancelSomething2();}// 回滚分布式事务 globalTransactionContext.rollback();}
}
全局事务上下文对象
@Component
public class GlobalTransactionContext {private Map<String, Object> results = new HashMap<>();public void addResult(String key, Object value) {results.put(key, value);}public Object getResult(String key) {return results.get(key);}public void commit() {// 提交分布式事务}public void rollback() {// 回滚分布式事务}
}
相关文章:
SSM 如何使用 TCC 机制实现分布式事务?
SSM 如何使用 TCC 机制实现分布式事务? 分布式事务是现代分布式系统中必不可少的一部分,而 TCC 机制(Try-Confirm-Cancel)是一种常用的分布式事务处理方式。在 SSM 框架中,我们可以使用 TCC 机制来管理分布式事务。本…...
如何在上架App之前设置证书并上传应用
App上架教程 在上架App之前想要进行真机测试的同学,请查看《iOS- 最全的真机测试教程》,里面包含如何让多台电脑同时上架App和真机调试。 P12文件的使用详解 注意: 同样可以在Build Setting 的sign中设置证书,但是有点麻烦&…...
华清远见 day04
break 打破循环,再也不执行 continue 跳出本次循环,继续执行下一次循环; 常量 字面常量 宏常量 #define A 100 //定义一个宏常量, 名为:A 值为:100 位置 在 头文件 下面 ,文件开头 输入时间秒 得到 小时 分钟 秒的时间输出 用到 三运算符; 宏常量 Mi 是60 t1 /Mi>6…...
如何处理Vue应用程序中的错误和异常情况?
处理Vue应用程序中的错误和异常情况是开发中非常重要的一环,但是对于新手来说,这往往是一个比较棘手的问题。不过别担心,下面我将为大家详细解答。 首先,我们需要知道的是,在Vue中,错误和异常情况是两个不…...
javascript基础十六:Ajax 原理是什么?如何实现?
一、是什么 AJAX全称(Async Javascript and XML) 即异步的JavaScript 和XML,是一种创建交互式网页应用的网页开发技术,可以在不重新加载整个网页的情况下,与服务器交换数据,并且更新部分网页 Ajax的原理简单来说通过XmlHttpRequ…...
大话手游原始服务端搭建教程Centos
大话手游原始服务端搭建教程Centos 大家好,我是艾西,今天给大家分享一款回合制的ARPG大话手游搭建教程。游戏场景、精美的画面以及多元的人物做的非常棒。在游戏中可以穿越神话世界,同时也可以结交好友,加入团队,共同…...
C语言中的通用工具库stdlib.h
目录 1、malloc和free:用于动态内存分配和释放。 2、atoi和atof:用于将字符串转换为整数或浮点数。 3、rand和srand:用于生成随机数和设置随机数种子。 4、system:用于执行系统命令。 5、exit:用于退出程序。 6、…...
优化带排序的分页查询
优化带排序的分页查询 浅分页: select user_no,user_name,socre from student order by score desc limit 5,20 深分页: select user_no,user_name,socre from student order by score desc limit 80000,20 因为偏移量深分页更大,所以深分页执…...
chatgpt赋能python:Python如何删除空白
Python 如何删除空白 在SEO优化过程中,我们需要保证我们的网页内容的质量和可读性。其中,一个重要的因素是删除空白。在Python中,我们可以使用多种方法来删除空白,下面我们将介绍一些方法并讨论它们的优缺点。 方法一࿱…...
[论文阅读] Explicit Visual Prompting for Low-Level Structure Segmentations
[论文地址] [代码] [CVPR 23] Abstract 我们考虑了检测图像中低层次结构的通用问题,其中包括分割被操纵的部分,识别失焦像素,分离阴影区域,以及检测隐藏的物体。每个问题通常都有一个特定领域的解决方案,我们表明&am…...
swagger在spring项目中的使用
一、Swagger2介绍 前后端分离开发模式中,api文档是最好的沟通方式。 Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。 及时性 (接口变更后,能够及时准确地通知相关前后端开发人员)规范性 (并且保…...
操作系统第五章——输入输出管理(中)
提示:若我会见到你,事隔经年,我如何向你招呼,以眼泪,以沉默 文章目录 5.2.1 IO核心子系统知识总览功能要在那个层次实现 5.2.2 假脱机技术(SPOOLing)知识总览什么是脱机技术假脱机技术——输入井…...
【网络】socket套接字基础知识
目录 IP地址和端口号 源IP地址和目的IP地址 端口号 源端口号和目的端口号 TCP/UDP协议 网络字节序 大小端 如何定义网络数据流地址 网络字节序和主机字节序的转换 socket编程接口 sockaddr结构 IP地址和端口号 源IP地址和目的IP地址 在IP数据包头部中,会…...
Go语言介绍以及Go语言环境安装
初步介绍: Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。 Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源&am…...
FPGA纯verilog实现CameraLink视频接收和发送,附带工程源码和技术支持
目录 1、前言2、CameraLink协议基础3、目前我已有的CameraLink收发工程4、设计方案5、CameraLink解码模块详解6、CameraLink编码模块详解7、vivado工程详解8、上板调试验证9、福利:工程代码的获取 1、前言 FPGA实现CameraLink视频编解码目前有两种方案:…...
k8s中的service、api-server、kube-proxy有什么区别
在Kubernetes(K8s)中,Service、API Server和kube-proxy是三个不同的组件,它们在集群中扮演着不同的角色和功能。下面我将为你解释它们之间的区别: 1. Service(服务): Service是K8s中…...
记录::opencv编译,cmake编译vs动态库
环境:window7,cmake-gui,vs2013 opencv:3.4.4 opencv_contrib:3.4.4(nonfree模块,主要为了用sift) 链接:https://pan.baidu.com/s/1OXg2IRaxTLTVqM2PVR2ZFA 提取码&a…...
网易SmartAuto,中文编程就是爽
上一篇我们应该用中文编程发出来后,果不其然不少人很不以为然,还有直说“骗钱的,估计也没人会上当”。这样的反应是在预料之中。 行胜于言,我今天讲一个我们已经用了好几年的产品,用来做UI自动化测试的SmartAuto&#…...
适配器模式那么强大,该怎么使用呢?
适配器模式是一种常用的设计模式,它可以将两个不兼容的接口进行转换,从而使它们之间可以进行交互。在业务开发中,我们经常需要将不同的系统或服务进行整合,而这些系统或服务往往有着不同的接口和数据格式。适配器模式提供了一种解…...
[极客大挑战 2019]PHP1
既然提到了备份网站估计也是存在着网站备份文件,可以先用御剑扫一下 啥都没扫出来,但是上回做文件备份的题目时收集了一些关于常用备份文件的文件名和后缀,可以直接使用burp抓包爆破,果然爆破出一个www.zip文件 访问下载好文件就有…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...
【向量库】Weaviate 搜索与索引技术:从基础概念到性能优化
文章目录 零、概述一、搜索技术分类1. 向量搜索:捕捉语义的智能检索2. 关键字搜索:精确匹配的传统方案3. 混合搜索:语义与精确的双重保障 二、向量检索技术分类1. HNSW索引:大规模数据的高效引擎2. Flat索引:小规模数据…...
【基于阿里云搭建数据仓库(离线)】使用UDTF时出现报错“FlatEventUDTF cannot be resolved”
目录 问题: 可能的原因有: 解决方法: 问题: 已经将包含第三方依赖的jar包上传到dataworks,并且成功注册函数,但是还是报错:“FlatEventUDTF cannot be resolved”,如下:…...
Python基于蒙特卡罗方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融投资中,风险管理是确保资产安全和实现稳健收益的关键环节。随着市场波动性的增加,传统…...
c++ decltype关键字
decltype为类型推导关键字。 示例代码: // decltype也可用于函数模板编程: template<typename T, typename U> auto add(T t, U u) -> decltype(t u) {return t u; }// decltype推导函数返回类型 auto doubleNumFunc(int x) -> decltype(x * 2) {ret…...
基于fpga的疲劳驾驶检测
基于fpga的疲劳驾驶检测 前言一、系统硬件设计二、系统软件设计系统上板实验测试 前言 代码基于网络大佬代码进行修改的。限制性比较大,不太灵活,当个本科毕业设计还是够的。 基于FPGA的疲劳检测模块硬件设计以FPGA核心控制模块为中心,通过…...
