参考文章

分布式事务实战方案汇总 https://www.cnblogs.com/yizhiamumu/p/16625677.html

分布式事务原理及解决方案案例https://www.cnblogs.com/yizhiamumu/p/16662412.html

seata 下载及安装 https://www.cnblogs.com/yizhiamumu/p/16809123.html

Spring Cloud集成Seata分布式事务-TCC模式 https://www.cnblogs.com/yizhiamumu/p/16809367.html

Seata 四大模式详解 https://www.cnblogs.com/yizhiamumu/p/16809386.html

Seata 核心源码详解 https://www.cnblogs.com/yizhiamumu/p/16811722.html

Spring Cloud集成Seata分布式事务-TCC模式

本文将介绍基于Spring Cloud + feign 如何集成 Seata(1.4.0)的TCC模式。实际上,Seata的AT模式基本上能满足我们使用分布式事务80%的需求,但涉及不支持事务的数据库与中间件(如redis)等的操作,或AT模式暂未支持的数据库(目前AT支持Mysql、Oracle与PostgreSQL)、跨公司服务的调用、跨语言的应用调用或有手动控制整个二阶段提交过程的需求,则需要结合TCC模式。不仅如此,TCC模式还支持与AT模式混合使用。

一、TCC模式的概念

一个分布式的全局事务,整体是两阶段提交Try-[Comfirm/Cancel] 的模型。在Seata中,AT模式与TCC模式事实上都是两阶段提交的具体实现。他们的区别在于:

AT 模式基于支持本地 ACID 事务 的 关系型数据库(目前支持Mysql、Oracle与PostgreSQL):

一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。 二阶段 commit 行为:马上成功结束,自动异步批量清理回滚日志。 二阶段 rollback 行为:通过回滚日志,自动生成补偿操作,完成数据回滚。

相应的,TCC 模式,不依赖于底层数据资源的事务支持:

一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。 二阶段 commit 行为:调用 自定义的 commit 逻辑。 二阶段 rollback 行为:调用 自定义的 rollback 逻辑。

所谓 TCC 模式,是指支持把 自定义 的分支事务纳入到全局事务的管理中。

简单点概括,SEATA的TCC模式就是手工的AT模式,它允许你自定义两阶段的处理逻辑而不依赖AT模式的undo_log。

二、前提准备

三、TM与TCC-RM的搭建

本章着重讲基于Spring Cloud + Feign的TCC的实现,项目的搭建直接看源码(本工程提供了AT模式与TCC模式的DEMO)

DEMO工程源码

3.1 seata服务端的搭建

服务端搭建文档

3.2 TM的搭建

service-tm

3.3 RM-TCC的搭建

3.3.1 定义TCC接口

由于我们使用的是 SpringCloud + Feign,Feign的调用基于http,因此此处我们使用@LocalTCC便可。值得注意的是,@LocalTCC一定需要注解在接口上,此接口可以是寻常的业务接口,只要实现了TCC的两阶段提交对应方法便可,TCC相关注解如下:

  • @LocalTCC 适用于SpringCloud+Feign模式下的TCC
  • @TwoPhaseBusinessAction 注解try方法,其中name为当前tcc方法的bean名称,写方法名便可(全局唯一),commitMethod指向提交方法,rollbackMethod指向事务回滚方法。指定好三个方法之后,seata会根据全局事务的成功或失败,去帮我们自动调用提交方法或者回滚方法。
  • @BusinessActionContextParameter 注解可以将参数传递到二阶段(commitMethod/rollbackMethod)的方法。
  • BusinessActionContext 便是指TCC事务上下文

实例如下:

/**
* 这里定义tcc的接口
* 一定要定义在接口上
* 我们使用springCloud的远程调用
* 那么这里使用LocalTCC便可
*
* @author tanzj
*/
@LocalTCC
public interface TccService { /**
* 定义两阶段提交
* name = 该tcc的bean名称,全局唯一
* commitMethod = commit 为二阶段确认方法
* rollbackMethod = rollback 为二阶段取消方法
* BusinessActionContextParameter注解 传递参数到二阶段中
*
* @param params -入参
* @return String
*/
@TwoPhaseBusinessAction(name = "insert", commitMethod = "commitTcc", rollbackMethod = "cancel")
String insert(
@BusinessActionContextParameter(paramName = "params") Map<String, String> params
); /**
* 确认方法、可以另命名,但要保证与commitMethod一致
* context可以传递try方法的参数
*
* @param context 上下文
* @return boolean
*/
boolean commitTcc(BusinessActionContext context); /**
* 二阶段取消方法
*
* @param context 上下文
* @return boolean
*/
boolean cancel(BusinessActionContext context);
}

3.3.2 TCC接口的业务实现

为了保证代码的简洁,此处将路由层与业务层结合讲解,实际项目则不然。

  • 在try方法中使用@Transational可以直接通过spring事务回滚关系型数据库中的操作,而非关系型数据库等中间件的回滚操作可以交给rollbackMethod方法处理。
  • 使用context.getActionContext("params")便可以得到一阶段try中定义的参数,在二阶段对此参数进行业务回滚操作。
  • **注意1:**此处亦不可以捕获异常(同理切面处理异常),否则TCC将识别该操作为成功,二阶段直接执行commitMethod。
  • 注意2:TCC模式要开发者自行保证幂等和事务防悬挂
@Slf4j
@RestController
public class TccServiceImpl implements TccService { @Autowired
TccDAO tccDAO; /**
* tcc服务t(try)方法
* 根据实际业务场景选择实际业务执行逻辑或者资源预留逻辑
*
* @param params - name
* @return String
*/
@Override
@PostMapping("/tcc-insert")
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public String insert(@RequestBody Map<String, String> params) {
log.info("xid = " + RootContext.getXID());
//todo 实际的操作,或操作MQ、redis等
tccDAO.insert(params);
//放开以下注解抛出异常
//throw new RuntimeException("服务tcc测试回滚");
return "success";
} /**
* tcc服务 confirm方法
* 若一阶段采用资源预留,在二阶段确认时要提交预留的资源
*
* @param context 上下文
* @return boolean
*/
@Override
public boolean commitTcc(BusinessActionContext context) {
log.info("xid = " + context.getXid() + "提交成功");
//todo 若一阶段资源预留,这里则要提交资源
return true;
} /**
* tcc 服务 cancel方法
*
* @param context 上下文
* @return boolean
*/
@Override
public boolean cancel(BusinessActionContext context) {
//todo 这里写中间件、非关系型数据库的回滚操作
System.out.println("please manually rollback this data:" + context.getActionContext("params"));
return true;
}
}

3.3.3 在TM中开启全局事务,调用RM-TCC接口

Spring Cloud集成Seata分布式事务-TCC模式的更多相关文章

  1. Spring Cloud异步场景分布式事务怎样做?试试RocketMQ

    一.背景 在微服务架构中,我们常常使用异步化的手段来提升系统的 吞吐量 和 解耦 上下游,而构建异步架构最常用的手段就是使用 消息队列(MQ),那异步架构怎样才能实现数据一致性呢?本文主要介绍如何使用 ...

  2. Spring Cloud同步场景分布式事务怎样做?试试Seata

    一.概述 在微服务架构下,虽然我们会尽量避免分布式事务,但是只要业务复杂的情况下这是一个绕不开的问题,如何保证业务数据一致性呢?本文主要介绍同步场景下使用Seata的AT模式来解决一致性问题. Sea ...

  3. 微服务痛点-基于Dubbo + Seata的分布式事务(TCC模式)

    前言 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案. ...

  4. 微服务痛点-基于Dubbo + Seata的分布式事务(AT)模式

    前言 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案. ...

  5. Dubbo学习系列之十五(Seata分布式事务方案TCC模式)

    上篇的续集. 工具: Idea201902/JDK11/Gradle5.6.2/Mysql8.0.11/Lombok0.27/Postman7.5.0/SpringBoot2.1.9/Nacos1.1 ...

  6. SpringCloud微服务实战——搭建企业级开发框架(二十七):集成多数据源+Seata分布式事务+读写分离+分库分表

    读写分离:为了确保数据库产品的稳定性,很多数据库拥有双机热备功能.也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器:第二台数据库服务器,主要进行读的操作. 目前有多种方式实现读写分离,一种 ...

  7. Hmily:高性能异步分布式事务TCC框架

    Hmily框架特性 无缝集成Spring,Spring boot start. 无缝集成Dubbo,SpringCloud,Motan等rpc框架. 多种事务日志的存储方式(redis,mongdb, ...

  8. SEATA 分布式事务入门DEMO

    Simple Extensible Autonomous Transacation Architecture,seata是简单的.可扩展.自主性高的分布式架构 SEATA Server Configu ...

  9. Spring Cloud Alibaba Seata

    一.简介 官网地址:http://seata.io/zh-cn/ 1,概念 Seata是一款开源的分布式事务解决方案,致力于在微服务架构在提供高性能和简单一样的分布式事务服务. 2,处理过程 Tran ...

  10. Spring Cloud第九篇 | 分布式服务跟踪Sleuth

    ​ ​本文是Spring Cloud专栏的第九篇文章,了解前八篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cl ...

随机推荐

  1. Spring的全局(统一)异常处理

    异常处理的三种方式 使用 @ExceptionHandler 注解 实现 HandlerExceptionResolver 接口(SpringMVC) 使用 @RestControllerAdvice ...

  2. 怎么判断一个变量arr的话是否为数组(此题用 typeof 不行)?

    arr instanceof Array arr.constructor == Array Object.protype.toString.call(arr) == '[Object Array]'

  3. Acwing周赛分享

    Acwing 周赛28 题面1 给定一个由大写字母构成的字符串 s,请计算其中有多少个子序列 QAQ. 注意,子序列不需要连续. 提示:本题数据范围较小,可以直接三重循环枚举三个字母的位置. 输入格式 ...

  4. 算法金 | DL 骚操作扫盲,神经网络设计与选择、参数初始化与优化、学习率调整与正则化、Loss Function、Bad Gradient

    大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 今日 216/10000 抱个拳,送个礼 神经网络设计与选择 参数初始化与优化 学习率 ...

  5. oeasy教您玩转vim - 20 - 显示标尺

    显示标尺 回忆上节课内容 定义标记 a ma 删除标记 a :delm a 跳转到标记 a 'a `a 跳到 a 对应的行和列 'a 跳到 a 对应的行 查看所有标记 :marks 各种标记类型 '' ...

  6. vscode 调试 nodejs 程序

    nodejs 服务在vscode 中的调试 1.安装vscode 略(这不用说了吧) 2.写一个能跑的nodejs 程序 其实看到这个,自己已经有一个能跑的nodejs 程序,不用看我的了 我这里是我 ...

  7. MFC--教你如何使用画刷(2)

    接下来我们用另外一个类CClientDC来实现我们的画线功能. CClientDC是由CDC派生出来的一个类,在函数构造的时候就会去调用GetDC来获得一个句柄,而在析构的时候便调用ReleaseDC ...

  8. 「图论」Bron-kerbosch算法

    7.21晚上加赛 T2.七负我,做这题找到了性质发现需要求最大团,不会,爆搜,打假了,赛后改,对了,但时间复杂度大爆炸,看下发题解,有这么一句话:于是学习了一下. Bron-kerbosch算法-求图 ...

  9. 为什么是Google创造了AlphaGo,而不是其他公司?

    相关: Artificial Intelligence | 60 Minutes Full Episodes 答案: Google一直在进行AI方向的探索: Google有足够的算力.

  10. windows系统下最新版gym[atari]中的游戏环境(此时最新版的gym为0.24.0,gym==0.24.0)

    关于gym[atari]的安装参看以前的博文: windows系统下安装最新版gym的安装方法(此时最新版的gym为0.24.0,gym==0.24.0) 上代码: import time impor ...