怎么看网站关键词密度,杭州知名app技术开发公司,网站平台结构,搜索引擎营销推广方案前言
该博客为Sentinel学习笔记#xff0c;主要目的是为了帮助后期快速复习使用 学习视频#xff1a;7小快速通关SpringCloud 辅助文档#xff1a;SpringCloud快速通关 源码地址#xff1a;cloud-demo
一、简介
官网#xff1a;https://seata.apache.org/zh-cn/ Seata …前言
该博客为Sentinel学习笔记主要目的是为了帮助后期快速复习使用 学习视频7小快速通关SpringCloud 辅助文档SpringCloud快速通关 源码地址cloud-demo
一、简介
官网https://seata.apache.org/zh-cn/ Seata 是一款开源的分布式事务解决方案旨在解决微服务架构中跨服务的事务一致性问题。它支持多种事务模型如AT、TCC、SAGA能够保证跨多个服务和数据库的数据一致性简化了分布式事务的管理。
为什么需要使用 Seata
在分布式系统中由于涉及多个微服务和多个数据库事务的一致性和可靠性成为了一个挑战。传统的事务管理机制如两阶段提交不适用于复杂的微服务环境因为它们的成本高、实现复杂且不易扩展。 Seata 的优势体现在以下几个方面
分布式事务支持Seata 提供了跨多个服务和数据库的事务支持确保多个服务的操作能够像一个单一事务一样进行提交或回滚。性能优化Seata 采用高效的事务协调机制通过减少分布式事务处理的开销显著提升系统性能。可靠性和容错性Seata 的设计保证了事务的一致性和可靠性即使在部分节点发生故障时也能保证系统的正确性。简化开发使用 Seata 时开发者不需要自己编写复杂的分布式事务处理逻辑Seata 提供了易用的注解和API极大地简化了开发工作。灵活的事务模型Seata 提供了多种事务模型AT、TCC、SAGA可以根据具体业务场景选择合适的事务管理方式满足不同的需求。
二、快速入门
2.1 环境准备 2.2 原理 2.2.1 核心组件
Seata分布式事务的工作原理主要涉及三个核心组件事务协调器TC、事务管理器TM和资源管理器RM。以下是这些组件的详细工作原理
事务协调器TCTC负责维护全局事务的状态并协调事务的提交或回滚。 它接收全局事务的开始、提交或回滚请求协调各个服务的事务执行。TC在收到所有分支事务的提交或回滚确认后将全局事务状态标记为结束。事务管理器TMTM负责定义和发起全局事务。 当TM发起一个全局事务时TC创建一个全局事务ID并将该事务状态设置为“开始”状态。TM通知TC提交事务TC依次通知各RM提交其分支事务。如果任一分支事务执行失败或出现异常TM通知TC回滚事务TC会依次通知各RM进行回滚操作。资源管理器RMRM负责管理分支事务Branch Transaction并与本地数据库资源交互确保各个分支事务的提交和回滚操作。 在全局事务的生命周期内多个服务会分别执行属于自己的本地事务即分支事务。每个分支事务在执行前需要向TC注册并绑定到全局事务ID上。每个服务的RM负责管理分支事务的执行并与本地资源交互。执行完成后RM会向TC报告分支事务的执行结果。
2.2.1 实现步骤
Seata的分布式事务管理通过以下步骤实现
全局事务开始当TM发起一个全局事务时TC创建一个全局事务ID并将该事务状态设置为“开始”状态。注册分支事务在全局事务的生命周期内多个服务会分别执行属于自己的本地事务即分支事务。每个分支事务在执行前需要向TC注册并绑定到全局事务ID上。分支事务执行每个服务的RM负责管理分支事务的执行并与本地资源交互。执行完成后RM会向TC报告分支事务的执行结果。全局提交或回滚当所有分支事务都执行成功时TM通知TC提交事务TC依次通知各RM提交其分支事务。如果任一分支事务执行失败或出现异常TM通知TC回滚事务TC会依次通知各RM进行回滚操作。事务结束TC在收到所有分支事务的提交或回滚确认后将全局事务状态标记为结束。
2.3 seata-server
下载https://seata.apache.org/zh-cn/download/seata-server解压并启动seata-server.bat Server端口【TC事务协调者】8091 Web可视化界面http://localhost:7091账号和密码都为seata
2.4 微服务配置
2.4.1 引依赖 !-- 分布式事务Seata --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-seata/artifactId/dependency2.4.2 配置
每个微服务创建 file.conf文件完整内容如下 【微服务只需要复制 service 块配置即可】
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the License); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an AS IS BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#transport {# tcp, unix-domain-sockettype TCP#NIO, NATIVEserver NIO#enable heartbeatheartbeat true# the tm client batch send request enableenableTmClientBatchSendRequest false# the rm client batch send request enableenableRmClientBatchSendRequest true# the rm client rpc request timeoutrpcRmRequestTimeout 2000# the tm client rpc request timeoutrpcTmRequestTimeout 30000# the rm client rpc request timeoutrpcRmRequestTimeout 15000#thread factory for nettythreadFactory {bossThreadPrefix NettyBossworkerThreadPrefix NettyServerNIOWorkerserverExecutorThread-prefix NettyServerBizHandlershareBossWorker falseclientSelectorThreadPrefix NettyClientSelectorclientSelectorThreadSize 1clientWorkerThreadPrefix NettyClientWorkerThread# netty boss thread sizebossThreadSize 1#auto default pin or 8workerThreadSize default}shutdown {# when destroy server, wait secondswait 3}serialization seatacompressor none
}
service {#transaction service group mappingvgroupMapping.default_tx_group default#only support when registry.typefile, please dont set multiple addressesdefault.grouplist 127.0.0.1:8091#degrade, current not supportenableDegrade false#disable seatadisableGlobalTransaction false
}client {rm {asyncCommitBufferLimit 10000lock {retryInterval 10retryTimes 30retryPolicyBranchRollbackOnConflict true}reportRetryCount 5tableMetaCheckEnable falsetableMetaCheckerInterval 60000reportSuccessEnable falsesagaBranchRegisterEnable falsesagaJsonParser fastjsonsagaRetryPersistModeUpdate falsesagaCompensatePersistModeUpdate falsetccActionInterceptorOrder -2147482648 #Ordered.HIGHEST_PRECEDENCE 1000sqlParserType druidbranchExecutionTimeoutXA 60000connectionTwoPhaseHoldTimeoutXA 10000}tm {commitRetryCount 5rollbackRetryCount 5defaultGlobalTransactionTimeout 60000degradeCheck falsedegradeCheckPeriod 2000degradeCheckAllowTimes 10interceptorOrder -2147482648 #Ordered.HIGHEST_PRECEDENCE 1000}undo {dataValidation trueonlyCareUpdateColumns truelogSerialization jacksonlogTable undo_logcompress {enable true# allow zip, gzip, deflater, lz4, bzip2, zstd default is ziptype zip# if rollback info size threshold, then will be compress# allow k m g tthreshold 64k}}loadBalance {type XIDvirtualNodes 10}
}
log {exceptionRate 100
}
tcc {fence {# tcc fence log table namelogTableName tcc_fence_log# tcc fence log clean periodcleanPeriod 1h}
}2.4.3 开启全局事务
在最大的方法入口标记GlobalTransactional即可开启全局事务
2.5 二阶提交协议原理
第一阶段本地事务
全局事务开始业务层发起全局事务请求事务协调者TC注册全局事务并生成全局事务ID。分支事务注册各个分支事务如扣减库存、创建订单、扣减余额分别向TC注册申请必要的资源锁如数据库表的记录锁。执行本地事务 扣减库存扣减库存执行SQL update storage_tbl set count count - 2 where commodity_code P0001更新库存数量。创建订单执行订单创建相关的本地事务。扣减余额执行扣减账户余额的本地事务。 记录前后镜像在执行业务SQL前后分别查询并记录数据的前后镜像用于生成回滚日志UNDO LOG。插入回滚日志将前后镜像组成的回滚日志插入到UNDO LOG表中以便在需要时进行数据回滚。本地事务提交将业务数据和UNDO LOG一起保存并汇报自己提交成功与否的结果。
第二阶段提交阶段
分支提交 收到TC的提交请求后各个分支事务立即响应OK表示准备就绪。给异步任务队列中添加异步任务异步和批量地删除相应的UNDO LOG记录。 分支回滚 如果TC的提交请求未能成功或者在第一阶段中某个分支事务失败TC将发起回滚请求。各个分支事务收到回滚请求后开启一个本地事务执行以下任务 找到对应的UNDO LOG记录。数据校验比较后镜像与当前数据如果不一致则说明数据被其他渠道修改需要进行相应处理如果一致则执行回滚。回滚数据根据UNDO LOG的前镜像内容执行数据修改完成后删除UNDO LOG。
通过以上流程Seata确保了分布式事务的原子性即所有分支事务要么全部成功提交要么全部回滚从而保证了数据的一致性。
2.6 二阶提交协议可视化
2.6.1 观察初始数据库 2.6.2 设置断点
我们在业务服务BusinessServiceImpl的主方法purchase中给远程调用方法deduct和create加上断点 并在订单服务OrderServiceImpl的create方法中添加一个除零异常并在前面加上一个断点
2.6.3 发起请求观察数据变化
在浏览器发送请求http://localhost:11000/purchase?userId1commodityCodeP0001count2 这里我们来到第一个断点扣减库存deduct可以看到控制台打印开启了一个新的全局事务 此时在Seata控制台中可以观测到这个全局事务 当前没有任何数据提交即没有全局锁 - 只有第一阶段本地提交要修改数据之前才会申请自己数据的记录锁即全局锁 继续放行到第二个断点位置创建订单create观察Seata控制台开启分支事务并查看 可以看到storage_db的分支事务 而且在全局锁中也可以看到数据 - 分支事务一定会提交一个数据 继续观察storage_db数据库可以看到库存已经被扣减并且在undo_log表中有一条记录 查看rollback_info字段的内容 在前镜像 beforeImage 中可以看到在记录修改之前的值为100 value: 100 后镜像afterImage扣减库存后的数据为value: 98
{class: org.apache.seata.rm.datasource.undo.BranchUndoLog,xid: 192.168.4.105:8091:7782838703486791689,branchId: 7782838703486791690,sqlUndoLogs: [java.util.ArrayList,[{class: org.apache.seata.rm.datasource.undo.SQLUndoLog,sqlType: UPDATE,tableName: storage_tbl,beforeImage: {class: org.apache.seata.rm.datasource.sql.struct.TableRecords,tableName: storage_tbl,rows: [java.util.ArrayList,[{class: org.apache.seata.rm.datasource.sql.struct.Row,fields: [java.util.ArrayList,[{class: org.apache.seata.rm.datasource.sql.struct.Field,name: count,keyType: NULL,type: 4,value: 100},{class: org.apache.seata.rm.datasource.sql.struct.Field,name: id,keyType: PRIMARY_KEY,type: 4,value: 1}]}}]]},afterImage: {class: org.apache.seata.rm.datasource.sql.struct.TableRecords,tableName: storage_tbl,rows: [java.util.ArrayList,[{class: org.apache.seata.rm.datasource.sql.struct.Row,fields: [java.util.ArrayList,[{class: org.apache.seata.rm.datasource.sql.struct.Field,name: count,keyType: NULL,type: 4,value: 98},{class: org.apache.seata.rm.datasource.sql.struct.Field,name: id,keyType: PRIMARY_KEY,type: 4,value: 1}]}}]]}}]]
}继续放行到第三个断点位置保存订单orderTblMapper.insert(orderTbl);观察Seata控制台 可以看到多了account_db的分支事务和全局锁 此时数据库的余额和库存均被扣减并且生成了UNDO LOG记录 此时继续放行即会执行int i 1/0;抛出除零异常所有数据全部按照前镜像回滚UNDO LOG记录 注意事务事务超时时间为一分钟调试过程中一旦超时会报一下错误 may be has finished - 事务可能完成 branch register failed - 分支注册事务失败 2025-02-13T22:41:16.01008:00 ERROR 19556 --- [seata-storage] [io-13000-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.transaction.TransactionSystemException: JDBC commit failed] with root causeorg.apache.seata.core.exception.RmTransactionException: branch register failed, xid: 192.168.4.105:8091:7782838703486791747, errMsg: TransactionException[Could not found global transaction xid 192.168.4.105:8091:7782838703486791747, may be has finished.]
2.7 四种事务模式
2.7.1 AT模式
这是Seata中最常用的一种分布式事务模式它通过自动的预提交、回滚操作实现分布式事务的透明化管理。AT模式的核心在于自动处理数据库的事务操作不需要对业务代码进行侵入性的修改。
2.7.2 TCC模式
适用于需要显式控制分布式事务的场景确保所有参与者都遵循统一的规则。TCC模式通过三阶段的提交Try、Confirm、Cancel来保证最终一致性。适用于夹杂非数据库操作的事务。
2.7.3 Saga模式
适用于复杂的业务流程每个步骤都可以独立地进行业务逻辑处理。在Saga模式中业务流程中每个参与者都提交本地事务当出现某一个参与者失败则补偿前面已经成功的参与者一阶段正向服务和二阶段补偿服务都由业务开发实现。
2.7.4 XA模式
适用于需要兼容传统数据库系统的场景支持多种资源管理器。XA模式是强一致性分阶段事务模式牺牲了一定的可用性无业务侵入。
2.7.5 切换模式
添加application.yml配置
seata:data-source-proxy-mode: AT #默认为AT模式