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文件 访问下载好文件就有…...

PID 学习
采样数据: X 1 , X 2 , X 3 . . . , X ( k − 1 ) , X k X_1,X_2,X_3...,X_(k-1),X_k X1,X2,X3...,X(k−1),Xk E k S v − X k E_kS_v-X_k EkSv−Xk ( S v S_v Sv 是用户设定值) 比例算法: O U T P K p ∗ E k O U T 0 OUT_PK_p*…...

002. java.lang.NumberFormatException: Infinite or NaN,怎么破?
你好,我是YourBatman:当我老了,也写代码;不为别的,只为爱好。 📚前言 如果你工作超5年,100%遇到过这个异常:java.lang.NumberFormatException: Infinite or NaN Infinite中文释义…...

Vue常用的修饰符
Vue常用的修饰符有哪些有什么应用场景 修饰符是什么 在Vue中,修饰符处理了许多DOM事件的细节,让我们不再需要花大量的时间去处理这些烦恼的事情,而能有更多的精力专注于程序的逻辑处理 分类、有5种 表单修饰符事件修饰符鼠标按键修饰符键…...

freertos笔记-任务切换
红叶何时落水 任务切换,调用PendSV #define taskYIELD() portYIELD() #define portYIELD() \ { \portNVIC_INT_CTRL_REG portNVIC_PENDSVSET_BIT; \ 通过向中断控制和壮态寄存器 ICSR 的 bit28 写入 1 挂起 PendSV 来启动 PendSV 中断\__dsb( portSY_FULL_READ…...

企业电子招投标采购系统源码之登录页面-java spring cloud
信息数智化招采系统 服务框架:Spring Cloud、Spring Boot2、Mybatis、OAuth2、Security 前端架构:VUE、Uniapp、Layui、Bootstrap、H5、CSS3 涉及技术:Eureka、Config、Zuul、OAuth2、Security、OSS、Turbine、Zipkin、Feign、Monitor、…...

接口测试|Fiddler弱网测试
Fiddler进行弱网测试 弱网测试 概念:弱网看字面意思就是网络比较弱,我们通称为信号差,网速慢。 意义:模拟在地铁、隧道、电梯和车库等场景下使用APP ,网络会出现延时、中断和超时等情况。 在这里插入图片描述 Fidd…...

Linux-0.11 文件系统super.c详解
Linux-0.11 文件系统super.c详解 模块简介 该模块主要包含了对超级块的一些读写操作。 函数详解 lock_super static void lock_super(struct super_block * sb)该函数的作用是锁定bh块。 cli();//关中断while (sb->s_lock)//如果已经被锁定sleep_on(&(sb->s_wai…...

什么是ChatGPT、历史发展及应用领域
什么是ChatGPT ChatGPT是一种基于深度学习的自然语言处理技术,它可以生成高质量的自然语言文本,该技术是由OpenAI团队开发,旨在使计算机能够像人类一样理解和产生自然语言。ChatGPT使用了深度神经网络和自然语言处理技术,通过对大…...

Spring的创建与使用
目录 1.创建 Spring 项⽬ 1.1 创建一个 maven 项目 1.2 添加 spring 框架支持(spring-context/spring-beans) 2.将 Bean (对象) 存储到 Spring (容器) 中 2.1 在resources中创建一个spring配置文件 2.2 将 Bean 对象存储到 Spring 当中 2.2.1 创建 Bean 对象 2.2.2 将B…...

抖音Flutter插件的使用
Flutter是一个开源的移动应用程序开发框架,由谷歌开发,支持Android和iOS。随着Flutter的发展和成熟,许多人开始使用它来开发跨平台应用程序。本文将介绍如何使用抖音的Flutter插件,以增强Flutter应用程序的功能。 1. 安装Flutter…...