分布式事务-seata AT模式-强一致性。

2023-11-11

目录

1.seata原理

2.关键组件

3.seate服务端参数

4.微服务配置

5.业务流程

6.依次启动eureka、seate服务器、微服务


1.seata原理

    Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC(类似2PC)、SAGA(长事务解决方案、基于状态机),为用户打造一站式的分布式解决方案。

    AT模式同tx-lcn类似,通过代理底层数据库连接,控制数据库事务的提交与回滚(必须依赖数据库);当然seate由于是由阿里维护的,同时支持多种注册中心,zookeeper、eureka等。

名词解释: TC 事务协调者、TM 事务管理器、RM 资源管理器、Microservices 微服务、DB 数据库

参考链接:

seate主项目:GitHub - seata/seata: Seata is an easy-to-use, high-performance, open source distributed transaction solution.

seate模板:seata-samples/springcloud-eureka-feign-mybatis-seata at master · seata/seata-samples · GitHub

seate快速使用:Quick Start

2.关键组件

  eureka、seate-0.8.0服务端、微服务1(hello)、微服务2(feign-consumer)

  spring boot:2.1.8.RELEASE

  spring cloud:Greenwich.SR2

  代码链接:GitHub - kickTec/springCloudDemo at transaction-seate

  csdn链接:transaction-seate.rar-Java文档类资源-CSDN下载

3.seate服务端参数

主要指定host,多个网卡自动绑定IP有时不对

    @Parameter(names = "--help", help = true)
    private boolean help;
    @Parameter(names = {"--host", "-h"}, description = "The ip to register to registry center.", order = 1)
    private String host;
    @Parameter(names = {"--port", "-p"}, description = "The port to listen.", order = 2)
    private int port = SERVER_DEFAULT_PORT;
    @Parameter(names = {"--storeMode", "-m"}, description = "log store mode : file, db", order = 3)
    private String storeMode;
    @Parameter(names = {"--serverNode", "-n"}, description = "server node id, such as 1, 2, 3.it will be generated according to the snowflake by default", order = 4)
    private Long serverNode;
    @Parameter(names = {"--seataEnv", "-e"}, description = "The name used for multi-configuration isolation.",
        order = 5)

windows启动seate服务器

seata-server.bat -h 192.168.0.18

4.微服务配置

maven配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.8.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.kenick</groupId>
	<artifactId>feign-consumer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>feign-consumer</name>
	<description>feign-consumer</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<!--数据库-->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.0.0</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<!-- pageHelper分页插件 -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>4.0.0</version>
		</dependency>

		<!--druid-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.10</version>
			<exclusions>
				<exclusion>
					<artifactId>slf4j-api</artifactId>
					<groupId>org.slf4j</groupId>
				</exclusion>
			</exclusions>
		</dependency>

		<!--lombok-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.8</version>
		</dependency>

		<!--seata-->
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-alibaba-seata</artifactId>
			<version>2.1.0.RELEASE</version>
			<exclusions>
				<exclusion>
					<artifactId>seata-all</artifactId>
					<groupId>io.seata</groupId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>io.seata</groupId>
			<artifactId>seata-all</artifactId>
			<version>1.2.0</version>
		</dependency>

		<!--eureka client-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>

		<!--feign-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
		</dependency>
	</dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

seate特殊配置(seate服务器和微服务指定相同的tx-service-group):

spring.cloud.alibaba.seata.tx-service-group=my_test_tx_group

file.conf文件中设置:

  #transaction service group mapping
  vgroupMapping.my_test_tx_group = "default"
  #only support when registry.type=file, please don't set multiple addresses
  default.grouplist = "192.168.0.18:8091"

register.conf中指定使用eureka:

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "eureka"

  nacos {
    serverAddr = "localhost"
    namespace = "public"
    cluster = "default"
  }
  eureka {
    serviceUrl = "http://192.168.0.105:8888/eureka"
    application = "default"
    weight = "1"
  }

由于seate AT模式是通过代理数据库连接方式实现的,在每个service服务中都需要进行如下配置:

/**
 * 数据源代理
 */
@Configuration
public class DataSourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }

    @Primary
    @Bean("dataSource")
    public DataSourceProxy dataSource(DataSource druidDataSource){
        return new DataSourceProxy(druidDataSource);
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception{
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSourceProxy);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mybatis/mapping/*Mapper.xml"));
        sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
        return sqlSessionFactoryBean.getObject();
    }

}

全局事务使用,在service上添加注释

    @GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class)
    @Override
    public int saveUser(String userId, String name, int age) {
        logger.debug("本地开始保存用户!");
        User user = new User();
        user.setUserId(userId);
        user.setName(name);
        user.setAge(age);
        int ret = userMapper.insert(user);
        logger.debug("本地开始保存用户结果:" + ret);

        logger.debug("开始远程调用helloservice!");
        String remoteRet = helloService.addUser("remote_hello" + userId, name, age);
        logger.debug("远程调用helloservice结果:" + remoteRet);

        // 产生异常
        // int num = 1/0;
        return ret;
    }

其它的请参考项目代码配置。

5.业务流程

    调用feign-consumer工程的addUser接口,接口逻辑:先在本地保存用户,再调用hello服务的保存用户接口,相当于一次调用保存2了个用户信息。

6.依次启动eureka、seate服务器、微服务

正常流程

调用feign-consumer接口(192.168.0.18:4001/addUser),先在当前服务添加用户,再调用另一个微服务hello添加用户;2个用户信息添加成功;全局事务执行情况见下图。

feign-consumer日志

hello日志

异常流程:两次用户都保存成功后,后续feign-consumer 服务异常,最终两个工程都进行了回退。

feign-consumer日志

hello日志

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

分布式事务-seata AT模式-强一致性。 的相关文章

  • 【业务功能篇104】 补充【业务功能篇99】微服务-springcloud-springboot-电商订单模块--整合支付

    在前面我们业务功能篇98 99中 我们介绍了电商项目中的订单模块服务 那么最后就是需要进行支付动作 那么我们这里就通过订阅第三方平台支付宝的支付调用接口功能 来进一步完成订单提交后的支付动作 支付宝的接口使用可以登录官网开发指南详情去了解
  • 区块链学习笔记(六)——区块链的分类

    文章目录 一 强调 二 公有链 联盟链 私有链 1 公有链 2 联盟链 3 私有链 总结 一 强调 先做一下重复强调 区块链技术是集分布式存储 点对点传输 共识机制 加密算法 数据区块等概念于一体的新兴技术集合 二 公有链 联盟链 私有链
  • Hi3516全系统类型烧录教程

    烧录资料下载 https gitee com hihope iot docs tree master HiSpark AI Camera Developer Kit Software tools 第一步 安装好hitool usb 烧写的驱
  • 记录一次生产环境MySQL死锁以及解决思路

    一 背景 1 业务背景 这里因为涉及到公司的业务问题不进行深入讨论 下面换成通用的一些业务场景就是举例 2 技术背景 众所周知 所谓锁的产生本质上是想解决资源竞争问题 在MySQL的前提下 MySQL为了解决事务并发独写的问题 在进行ins
  • 深度学习大模型训练--分布式 deepspeed PipeLine Parallelism 源码解析

    deepspeed PipeLine Parallelism 源码解析 basic concept PipeDream abstract 1F1B 4 steps Code comprehension in deepspeed prepar
  • java脚本引擎Groovy实战

    前言 互联网时代随着业务的飞速发展 不仅产品迭代 更新的速度越来越快 个性化需求也是越来越多 如何快速的满足各种业务的个性化需求是我们要重点思考的问题 我们开发的系统如何才能做到热部署 不重启服务就能适应各种规则变化呢 实现业务和规则的解耦
  • ZooKeeper踩坑

    一 下载安装包时要下载文件名中带有bin的安装包 否则会报错 找不到或无法加载主类 org apache zookeeper server quorum QuorumPeerMain Error contacting service 这是由
  • 一文打通Sleuth+Zipkin 服务链路追踪

    1 为什么用 微服务架构是一个分布式架构 它按业务划分服务单元 一个分布式系统往往有很多个服务单元 由于服务单元数量众多 业务的复杂性 如果出现了错误和异常 很难去定位 主要体现在 一个请求可能需要调用很多个服务 而内部服务的调用复杂性 决
  • 【seaweedfs】3、f4: Facebook’s Warm BLOB Storage System 分布式对象存储的冷热数据

    论文地址 Facebook的照片 视频和其他需要可靠存储和快速访问的二进制大型对象 BLOB 的语料库非常庞大 而且还在继续增长 随着BLOB占用空间的增加 将它们存储在我们传统的存储系统 Haystack 中变得越来越低效 为了提高我们的
  • Springboot结合Redis实现分布式定时任务

    一 背景 之前分享过分布式定时任务的技术选型方案 分布式定时任务技术选型方案 个人青睐xxl job 分享了搭建接入流程 xxl job搭建方案 本次项目需求较为简单 同时时间紧张 下面介绍利用Redis锁实现分布式定时任务的方案 二 Sc
  • 分布式系统详解--基础知识(通信)

    分布式系统详解 基础知识 通信 上一篇文章我们写到了 分布式系统详解 基础知识 线程 简单了解了一下线程的基本概念和线程和分布式的那斩不断理还乱的关系 今天再讲解一下它的另外一个必备知识 通信 进程之间进行通信是分布式的核心 失去了通信 也
  • 基于一致性理论的孤岛微电网分布式控制策略研究(Simulink仿真实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 仿真搭建 2 2 优化控制
  • 基于一致性理论的孤岛微电网分布式控制策略研究(Simulink仿真实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 仿真搭建 2 2 优化控制
  • 什么是自动化测试,看完你就懂了!

    随着互联网技术的飞速发展 软件本身的规模和复杂度也是逐步增加 为了保证软件项目能够保质保量交付到客户手中 软件测试环节就显得非常重要了 它可以看作是软件项目交付给客户最后一道安全保证 今天给大家聊聊软件测试当中自动化测试相关的知识 希望对大
  • 消息队列选型:Kafka 如何实现高性能?

    在分布式消息模块中 我将对消息队列中应用最广泛的 Kafka 和 RocketMQ 进行梳理 以便于你在应用中可以更好地进行消息队列选型 另外 这两款消息队列也是面试的高频考点 所以 本文我们就一起来看一下 Kafka 是如何实现高性能的
  • 网站被攻击了怎么恢复?如何在被攻击后第一时间接入高防恢复正常访问?

    网站受到攻击的原因是多种多样的 包括技术漏洞 人为疏忽 社会工程学等各种因素 保护网站的安全需要综合运用技术手段 当网站遭到攻击时 以下几个步骤可以帮助恢复网站的正常运行 1 分析攻击 首先要确认网站被攻击的类型和程度 以确定所需的恢复步骤
  • 终于找到了最新版的Zookeeper入门级教程,建议收藏!

    小熊学Java https javaxiaobear cn 1 分布式一致性 1 CAP 理论 CAP 理论指出对于一个分布式计算系统来说 不可能同时满足以下三点 一致性 在分布式环境中 一致性是指数据在多个副本之间是否能够保持一致的特性
  • Spark 中 BroadCast 导致的内存溢出(SparkFatalException)

    背景 本文基于 Spark 3 1 1 open jdk 1 8 0 352 目前在排查 Spark 任务的时候 遇到了一个很奇怪的问题 在此记录一下 现象描述 一个 Spark Application Driver端的内存为 5GB 一直
  • 【复现】遗传算法求解分布式电源选址定容问题并考虑环境因素研究【IEEE33节点】(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现
  • CAP与BASE理论

    CAP与BASE理论 CAP 一个分布式系统最多只能同时满足一致性 Consistency 可用性 Availability 和分区容错性 Partition tolerance 这三项中的两项 C一致性 状态的一致性 缓存 数据库 集群等

随机推荐

  • Gin框架(学习笔记)

    目录 学习地址 gin 路由 routes group gin 中间件 Cookie 重定向 同步异步 日志文件 学习地址 https www topgoer com gin E6 A1 86 E6 9E B6 gin 路由 package
  • windows操作系统蓝屏错误对照表

    windows操作系统蓝屏错误对照表
  • 出行行业计价模块的设计模式实践

    业务场景介绍 在出行行业中 价格的配置随随着业务的增加而增加 而刺激出行的促销活动更是频繁 在价格的计算中 通常的流程如下 根据一组价格配置 计算订单基础的价格 根据用户拥有的优惠对象 例如优惠券 积分 会员级别等 计算出优惠以后的价格 计
  • 信号和槽机制

    1 信号和槽机制概念 信号 各种事件 槽 响应信号的动作 当某个事件发生后 如某个按钮被点击了一下 它就会发出一个被点击的信号 signal 某个对象接收到这个信号之后 就会做一些相关的处理动作 称为槽slot 但是Qt对象不会无故收到某个
  • pyqt5 一些界面色彩搭配的建议(RGB值)

    简约现代风格 底色 浅灰色 240 240 240 按钮控件颜色 中蓝色 0 122 255 文字框颜色 白色 255 255 255 字体颜色 深灰色 51 51 51 点击时的颜色 深蓝色 0 80 180 清新自然风格 底色 浅绿色
  • React中styled-components的使用(样式组件库)

    一 官网地址 https www styled components com 二 styled components 1 styled components 样式化组件 主要作用是它可以编写实际的CSS代码来设计组件样式 也不需要组件和样式
  • React项目路由懒加载lazy、Suspense,使第一次打开项目页面变快

    一次性加载太多的路由文件会使首次加载的速度很慢 所以我们需要将路由搞成懒加载的形式 用到哪个组件加载哪个组件 庆幸的是React官方已经给我们准备好了插件 也在React库中 首先 从react这个库中导出lazy Suspense这两个方
  • mysql数据库的内部结构说明

    记住 表才是存放数据的基本单元 结论 Mysql数据底层由多个database组成 每一个database存放多张表
  • 【记录】在NAS上部署git文章汇总(网址)

    1 https blog csdn net mtclz3 article details 87461470 2 https blog csdn net u014213012 article details 65631261 3 https
  • git常用操作命令总结

    本篇文章主要收集记录git常用命令
  • Keil编程中Source Brower : "P17" is undefined!的问题

    博客原文 Keil编程中Source Brower P17 is undefined 的问题 在Keil新建工程中经常会遇到一个问题 去看某一个变量定义 然后跳转不过去 并提示Source Brower 某某 is undefined 在这
  • 嵌入式VSCode+gdbserver图形化调试环境搭建与使用

    目录 一 原理 二 环境搭建 1 VSCode设置 2 gdbserver安装 三 调试过程 一 原理 嵌入式系统中一般在 PC端运行 gdb工具 源码也是在 PC端 源码对应的可执行文件放到开发板中运行 为此我们需要在开发板中运行 gdb
  • 数据库分库分表

    一 为什么要分库分表 如果一个网站业务快速发展 那这个网站流量也会增加 数据的压力也会随之而来 比如电商系统来说双十一大促对订单数据压力很大 Tps十几万并发量 如果传统的架构 一主多从 主库容量肯定无法满足这么高的Tps 业务越来越大 单
  • Linux下Socket编程

    什么是Socket Socket接口是TCP IP网络的API Socket接口定义了许多函数或例程 程式员能够用他们来研发TCP IP网络上的应用程式 要学Internet上的TCP IP网络编程 必须理解Socket接口 Socket接
  • 七. Kubernetes Objects对象,对象状态与yaml

    目录 一 基础概念理解 二 k8s 对象中的spec与status 三 如何编写yaml 一 基础概念理解 Kubernetes Objects 官方地址 在k8s中所有操作资源实体都可以称为对象 先下图中的这些 都可以称为对象 不同对象功
  • 汇编语言随笔(10)-内中断及实验12(返回到dos的中断处理程序)

    不同类型内中断的区分 中断类型码 8086cpu中在下面4种情况下会产生内中断 1 除法错误 如之前提到的除法溢出 2 单步执行 3 执行into指令 4 执行int指令 那么当内中断发生时cpu如何来区分到底是哪种中断源呢 通过中断类型码
  • 代码随想录训练营day9

    题目一 实现strStr 力扣题目链接 题目描述 给你两个字符串 haystack 和 needle 请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标 下标从 0 开始 如果 needle 不是 haysta
  • GLSL的in、out存储限制符使用错误

    在GLSL中用in修饰的变量表示传入的数据 用out修饰的变量表示传出的数据 通过这样可以实现顶点着色器向片段着色器传递数据 但要注意这个变量的命名要相同 不相同的话 片段着色器是获取不到从顶点着色器传入的数据的 1 顶点着色器 versi
  • unity打包技巧

    打包准备 1 android 需要jdk 和android sdk 如果有使用C 的库 还需要NDK 只有将 so文件放在 Assets Plugins Android libs下 Unity才会将 so文件识别为共享库 并在打包时将之拷贝
  • 分布式事务-seata AT模式-强一致性。

    目录 1 seata原理 2 关键组件 3 seate服务端参数 4 微服务配置 5 业务流程 6 依次启动eureka seate服务器 微服务 1 seata原理 Seata 是一款开源的分布式事务解决方案 致力于提供高性能和简单易用的