SpringBoot+Seata在多数据源和feign中的简单使用
SpringBoot+Seata简单使用
目录
- seata执行过程
- 安装seata
- 下载seata
- 使用自定义配置文件,NACOS为注册中心
- 结合springboot实现AT模式
- 1.多数据源
- 引入依赖
- bootstrap.yml配置
- 在使用的方法上用@GlobalTransactional注解
- 调用接口正常时
- 调用接口报错时回滚
- 2.配合feign
- seata优缺点
seata执行过程
(官网的图)
安装seata
seata官网安装教程
下载seata
我选择了用docker下载选择1.6.1最新的版本,docker-compose启动,有个注意的细节,官网说明了
docker pull seataio/seata-server:1.6.1
使用自定义配置文件,NACOS为注册中心
先启动一次把application.yml配置文件放在宿主机中,(注意1.4.2之前是file.conf,配置写法也不相同)
docker run -d -p 8091:8091 -p 7091:7091 --name seata-serve seataio/seata-server:1.6.1
docker cp seata-serve:/seata-server/resources /home/seata/config
拷出后可以,可以选择修改application.yml再cp进容器,或者rm临时容器,如下重新创建,并做好映射路径设置,我选择了删除旧镜像使用docker-compose启动新的镜像。
找到/home/seata/config/resources/application.yml,修改对应的配置,详细配置文件里面有个 application.example.yml可以参考或者上官网查看
application.yml
server:port: 7091 #界面管理端口spring:application:name: seata-server #应用名称logging:config: classpath:logback-spring.xmlfile:path: ${user.home}/logs/seataextend:logstash-appender:destination: 127.0.0.1:4560kafka-appender:bootstrap-servers: 127.0.0.1:9092topic: logback_to_logstashconsole:user:username: seata #账号password: seata #密码seata:config:# support: nacos, consul, apollo, zk, etcd3 #支持的数据存储类型type: nacos #选择的数据类型为nacosnacos:server-addr: nacosIP:8848 #nacos地址namespace: seata #nacos命名空间group: SEATA_GROUP #组名usernam: nacos #账号password: xxx #密码data-id: seataServer.properties #读取的配置文件,官网有registry:# support: nacos, eureka, redis, zk, consul, etcd3, sofatype: nacosnacos:application: seata-serverserver-addr: nacosIP:8848group: SEATA_GROUPnamespace: seata# tc集群名称cluster: defaultusername: nacospassword: xxx #密码# store:# support: file 、 db 、 redis# mode: file# server:# service-port: 8091 #If not configured, the default is '${server.port} + 1000'security:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
dcoker-compose
version: "3"
services:seata-server:image: seataio/seata-server:1.6.1 #镜像container_name: my-seata #容器名称ports:- "8091:8091"- "7091:7091"environment:#一定要指定store_mode,因为application.yml没指定,如application.yml指定了这可以不指定。如无指定会出现全局数据开启失败的问题- STORE_MODE=db #指定为数据库,配置文件写在nacos# 以SEATA_IP作为host注册seata server- SEATA_IP=xx.xx.xx.xx #该IP一定是要服务能访问到的地址- SEATA_PORT=8091 #服务端口 volumes:- "/home/seata/config/resources:/seata-server/resources"- "/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime" #设置系统时区- "/usr/share/zoneinfo/Asia/Shanghai:/etc/timezone" #设置时区
nacos上的配置文件seataServer.properties,配置文件官方有官方配置
store.mode=db
#-----db-----
store.db.datasource=druid
store.db.dbType=mysql #指定数据库类型
# 需要根据mysql的版本调整driverClassName
# mysql8及以上版本对应的driver:com.mysql.cj.jdbc.Driver
# mysql8以下版本的driver:com.mysql.jdbc.Driver
store.db.driverClassName=com.mysql.cj.jdbc.Driver #在数据库执行select version()查看版本;
store.db.url=jdbc:mysql://xx.xx.xx.xx:3306/seata-server?useUnicode=true&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false
store.db.user= root
store.db.password=root
# 数据库初始连接数
store.db.minConn=1
# 数据库最大连接数
store.db.maxConn=20
# 获取连接时最大等待时间 默认5000,单位毫秒
store.db.maxWait=5000
# 全局事务表名 默认global_table
store.db.globalTable=global_table
# 分支事务表名 默认branch_table
store.db.branchTable=branch_table
# 全局锁表名 默认lock_table
store.db.lockTable=lock_table
# 查询全局事务一次的最大条数 默认100
store.db.queryLimit=100# undo保留天数 默认7天,log_status=1(附录3)和未正常清理的undo
server.undo.logSaveDays=7
# undo清理线程间隔时间 默认86400000,单位毫秒
server.undo.logDeletePeriod=86400000
# 二阶段提交重试超时时长 单位ms,s,m,h,d,对应毫秒,秒,分,小时,天,默认毫秒。默认值-1表示无限重试
# 公式: timeout>=now-globalTransactionBeginTime,true表示超时则不再重试
# 注: 达到超时时间后将不会做任何重试,有数据不一致风险,除非业务自行可校准数据,否者慎用
server.maxCommitRetryTimeout=-1
# 二阶段回滚重试超时时长
server.maxRollbackRetryTimeout=-1
# 二阶段提交未完成状态全局事务重试提交线程间隔时间 默认1000,单位毫秒
server.recovery.committingRetryPeriod=1000
# 二阶段异步提交状态重试提交线程间隔时间 默认1000,单位毫秒
server.recovery.asynCommittingRetryPeriod=1000
# 二阶段回滚状态重试回滚线程间隔时间 默认1000,单位毫秒
server.recovery.rollbackingRetryPeriod=1000
# 超时状态检测重试线程间隔时间 默认1000,单位毫秒,检测出超时将全局事务置入回滚会话管理器
server.recovery.timeoutRetryPeriod=1000
在seata使用的数据库上建立这几张表,官方有sql
CREATE TABLE `branch_table` (`branch_id` bigint NOT NULL,`xid` varchar(128) NOT NULL,`transaction_id` bigint DEFAULT NULL,`resource_group_id` varchar(32) DEFAULT NULL,`resource_id` varchar(256) DEFAULT NULL,`branch_type` varchar(8) DEFAULT NULL,`status` tinyint DEFAULT NULL,`client_id` varchar(64) DEFAULT NULL,`application_data` varchar(2000) DEFAULT NULL,`gmt_create` datetime(6) DEFAULT NULL,`gmt_modified` datetime(6) DEFAULT NULL,PRIMARY KEY (`branch_id`),KEY `idx_xid` (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;CREATE TABLE `distributed_lock` (`lock_key` char(20) NOT NULL,`lock_value` varchar(20) NOT NULL,`expire` bigint DEFAULT NULL,PRIMARY KEY (`lock_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;CREATE TABLE `global_table` (`xid` varchar(128) NOT NULL,`transaction_id` bigint DEFAULT NULL,`status` tinyint NOT NULL,`application_id` varchar(32) DEFAULT NULL,`transaction_service_group` varchar(32) DEFAULT NULL,`transaction_name` varchar(128) DEFAULT NULL,`timeout` int DEFAULT NULL,`begin_time` bigint DEFAULT NULL,`application_data` varchar(2000) DEFAULT NULL,`gmt_create` datetime DEFAULT NULL,`gmt_modified` datetime DEFAULT NULL,PRIMARY KEY (`xid`),KEY `idx_status_gmt_modified` (`status`,`gmt_modified`),KEY `idx_transaction_id` (`transaction_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;CREATE TABLE `lock_table` (`row_key` varchar(128) NOT NULL,`xid` varchar(128) DEFAULT NULL,`transaction_id` bigint DEFAULT NULL,`branch_id` bigint NOT NULL,`resource_id` varchar(256) DEFAULT NULL,`table_name` varchar(32) DEFAULT NULL,`pk` varchar(36) DEFAULT NULL,`status` tinyint NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',`gmt_create` datetime DEFAULT NULL,`gmt_modified` datetime DEFAULT NULL,PRIMARY KEY (`row_key`),KEY `idx_status` (`status`),KEY `idx_branch_id` (`branch_id`),KEY `idx_xid` (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
AT模式还要在对应的业务库加上undo_log表
CREATE TABLE `undo_log` (`id` bigint NOT NULL AUTO_INCREMENT,`branch_id` bigint NOT NULL,`xid` varchar(100) NOT NULL,`context` varchar(128) NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int NOT NULL,`log_created` datetime NOT NULL,`log_modified` datetime NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb3;
docker-compose up -d 后台启动seata
docker logs -f seata-server 查看执行日志
nacos上看到seata服务
IP:7091能登陆seata管理界面
结合springboot实现AT模式
1.多数据源
引入依赖
<!--多数据源--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId></dependency><!--seata--><dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.5.2</version></dependency>
bootstrap.yml配置
seata:enabled: true #开启enable-auto-data-source-proxy: false #关闭数据源代理,这里不关闭会出现事务回滚问题,具体可以查看application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name}tx-service-group: mytest-group # Seata 事务组编号,用于 TC 集群名registry:type: nacosnacos:application: seata-serverserver-addr: xx.xx.xx.xx:8848namespace: 332a6313-c96c-4c5d-b3b5-3063093bf8f9group: SEATA_GROUPconfig:type: nacosnacos:server-addr: xx.xx.xx.xx:8848namespace: 332a6313-c96c-4c5d-b3b5-3063093bf8f9group: SEATA_GROUP# 服务配置项,对应 ServiceProperties 类service:# 虚拟组和分组的映射vgroup-mapping:multi-datasource-service-group: default# 分组和 Seata 服务的映射grouplist:default: xx.xx.xx.xx:8091 #seata服务地址
(图片来源网络)
在使用的方法上用@GlobalTransactional注解
调用接口正常时
数据能正常拆入2个表中
调用接口报错时回滚
调用前,远程服务器的remotest表无数据
执行全局事务,TM申请了XID
执行远程数据插入,数据表出现数据的remotest表会删除刚插入的数据
本地数据库主键冲突报错,会执行全局事务的回滚,发现远程数据库
2.配合feign
开启2个服务注册到nacos上
调用方法,TM申请到了XID
远程服务获取到了相同的xid
执行完数据操作后,该服务RM会告诉TC执行完成
本地方法报错RM会告诉TC执行回滚,远程数据的RM也会被告知进行回滚
feign把xid添加到head中
String xid = RootContext.getXID();requestTemplate.header(RootContext.KEY_XID, xid);
public class FeignInterceptorConfig implements RequestInterceptor {Logger log = LoggerFactory.getLogger(FeignInterceptorConfig.class);public void apply(RequestTemplate requestTemplate) {RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();if (ObjectUtils.isEmpty(requestAttributes)){return ;}ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;HttpServletRequest request = attributes.getRequest();Enumeration<String> headerNames = request.getHeaderNames();//可以在这里将自定义请求头传递进去, key 请求, value 值//处理上游请求头信息,传递时继续携带if (headerNames != null) {while (headerNames.hasMoreElements()) {String name = headerNames.nextElement();String values = request.getHeader(name);// 跳过 content-lengthif ("content-length".equals(name)) {continue;}requestTemplate.header(name, values);}//传递 seata 的 xidString xid = RootContext.getXID();requestTemplate.header(RootContext.KEY_XID, xid);}else {log.info("feign interceptor error header:{}", requestTemplate);}}
}
如果开启了hystrix会导致添加的head失效,因为获取的ServletRequestAttributes是null,要修改hystrix的策略。
参考下文
hystrix开启导致feign添加head失效
feign:hystrix:enabled: true
hystrix:command:default:execution:timeout:#如果enabled设置为false,则请求超时交给ribbon控制enabled: trueisolation:# 隔离策略strategy: SEMAPHORE thread:timeoutInMilliseconds: 100000
seata优缺点
优点:
1.业务侵入性低
2.TC(事务协调者)服务端能单独部署,利用nacos等注册中心能起多个
(图片截取于网络)
缺点:
(图片截取于网络)
相关文章:

SpringBoot+Seata在多数据源和feign中的简单使用
SpringBootSeata简单使用 目录seata执行过程安装seata下载seata使用自定义配置文件,NACOS为注册中心结合springboot实现AT模式1.多数据源引入依赖bootstrap.yml配置在使用的方法上用GlobalTransactional注解调用接口正常时调用接口报错时回滚2.配合feignseata优缺点seata执行过…...

计算机网络中的原码、反码、补码
写在前面 原码、反码、补码是计算机组成原理中的概念,是计算机网络的基础知识之一。这些概念是为了处理二进制数的符号位而引入的,常用于计算机中的整数运算,也常用于数据存储和传输等领域。因此,了解和掌握这些概念对于理解计算机…...
七、Bean的实例化方式
Spring为Bean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活) 第一种:通过构造方法实例化第二种:通过简单工厂模式实例化第三种&…...

Windows程序员学习Linux环境下VI(VIM)编辑器的使用方法
我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Windows程序员如何学习Linux环境知识。由于很多程序在Windows环境下开发好后,还要部署到Linux服务器上去,所以作为Windows程序员有必要学习Linux环境的知识。VI…...
react入门篇
react入门篇前言一、目标二、项目环境三、实现过程(干货满满💥💥💥)1.创建react项目2.arco design UI库3.路由模块化4. 状态管理zustand5. axios6. 路由守卫前言 提示:这里可以添加本文要记录的大概内容&a…...

阿赵的MaxScript学习笔记分享九《可编辑多面体的操作》
大家好,我是阿赵。这是MaxScript学习笔记分享的第九篇,可编辑多面体的操作。不知不觉写了这么多篇了,应该还有几篇就写完了。自己给自己加一下油。 在3DsMax里面如果需要建模,一般使用到的塌陷方式有3种,可编辑的网格、…...

【Redis场景5】集群秒杀优化-分布式锁
集群环境下的秒杀问题 前序 【Redis场景1】用户登录注册 【Redis场景2】缓存更新策略(双写一致) 【Redis场景3】缓存穿透、击穿问题 【Redis场景拓展】秒杀问题-全局唯一ID生成策略 【Redis场景4】单机环境下秒杀问题 在单机环境下的并发问题,我们可以使用相关…...

transformer目标检测开山之作detr
1. 将一个batch的图片输入backone获得feature。 (2,c,w,h)先输入resnet50中,得到(2,2048,w,h)。虽然这里channel不是256,但是在输入e…...

双指针法|位运算|离散化|区间合并
目录 双指针算法 位运算 离散化 序列合并 双指针算法 题目描述:1.输入n个单词,每个单词在输入的时候按空格隔开,之后打印出每个单词且换行 #include<iostream> #include <string>using namespace std; int main() {strin…...

Rockchip Android13 GKI开发指南
Rockchip Android13 GKI开发指南 文章目录Rockchip Android13 GKI开发指南GKI介绍Google upstream kernel下载及编译Rockchip SDK中GKI相关目录介绍Rockchip GKI编译代码修改编译固件烧写KO编译及修改添加新的模块驱动的方法调试ko方法开机log确认uboot阶段Android阶段KO加载KO…...
手把手教你原生JavaScript打造丝滑流畅的轮播图,让你的网站瞬间提升用户体验!
简介 轮播图是网页设计中常见的交互组件之一,用于展示多张图片或内容,让用户能够方便地浏览、切换和选择。本文将介绍如何使用原生 JavaScript 手写一个简单的轮播图,并且通过代码解释实现细节。 目录 简介 HTML 结构 CSS 样式 JavaScr…...
git常用基本操作
克隆远程代码更新本地代码 git clone <-b | -branch> [branch name] [repository URL] git pull #拉取远程仓库代码,更新本地仓库 git merge <branch-name> #合并目标分支 建立本地仓库分支 git branch #查看当…...

剑指 Offer —— 数组和字符串
文章目录剑指 Offer 04. 二维数组中的查找代码实现解题方案 思路算法步骤剑指 Offer 05. 替换空格题目描述代码实现解题方案 思路算法步骤剑指 Offer 11. 旋转数组的最小数字 - 解决方案题目描述剑指 Offer 04. 二维数组中的查找 在一个 n * m 的二维数组中: 每…...

Java 字符编码
编码:数据存储进计算机中需要转换为二进制存储,这个过程就是编码。 解码:计算机读取数据并展示在页面上,需要将二进制转换为人类语言的过程,叫做解码。 乱码:如果编码和解码时使用的码表不一样,…...

ubuntu-9-安装chrony时间同步
使用chrony搭建时间同步服务器 [Linux系列]Chrony时间同步服务器 配置chrony服务,实现服务器时间自动同步 linux上内网环境配置NTP时间同步详解 经验体会:解决Ubuntu 18.04Windows双系统时间不同步的问题 1 时间同步 我们知道一台电脑主机,…...

CMMI流程规范—服务与维护
服务与维护(Service and Maintenance, SM)是指产品销售之后的客户服务和产品维护。客户服务和产品维护的宗旨就是提高客户对产品以及对开发方的满意度。服务与维护过程域是SPP模型的重要组成部分。本规范阐述了服务与维护过程域的两个主要规程࿱…...

【蓝桥杯集训12】DFS(3 / 5)
目录 842. 排列数字 - DFS按位置枚举 843. n-皇后问题 - DFS按行枚举 165. 小猫爬山 - DFS枚举小猫 1209. 带分数 - DFS 3502. 不同路径数 - 842. 排列数字 - DFS按位置枚举 活动 - AcWing 题目: 给你一个整数n 要求将1~n的所有排列情况列出 比如:…...

Elasticsearch:构建自动补全功能 - Autocomplete
什么是自动补全(autocomplete)功能呢?我们举一个很常见的例子。 每当你去谷歌并开始打字时,就会出现一个下拉列表,其中列出了建议。 这些建议与查询相关并帮助用户完成查询。 Autocomplete 正如维基百科所说的…...

One UI 5.1 更新来了
之前一直在关注One UI 5.0里提到的视频通话背景功能模块,结果5.0版本推送的时候没有引入,有先行者计划博主说是5.1里肯定会有的;前一两天One UI 5.1更新来了,然而该功能还是没有引入,表示很遗憾;本次更新新…...
Python学习笔记11:文件
文件 打开文件 函数open的参数mode的最常见取值 值描述‘r’读取模式(默认值)‘w’写入模式‘x’独占写入模式‘a’附加模式‘b’二进制模式(与其他模式结合使用)‘t’文本模式(默认值,与其他模式结合使…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...

向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...