微服务分布式事务解决方案Seata
文章目录
- 一、Seata是什么?
- 二、使用步骤
- 1.引入库
- 2.读入数据
- 总结
一、什么是Seata?
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用 的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事 务模式,为用户打造一站式的分布式解决方案(AT模式是阿里首推的模式, 阿里云上有商用版本的GTS[Global Transaction service 全局事务服务] ) 。
提示: 业务场景:
角色划分:
RM(ResourceManager 资源管理者)理解为我们的一个一个的微服务,也叫做事务的参与者. TM(TranactionManager 事务管理者) 也是我们的一个微服务,但是该微服务是 一个带头大哥,充当全局事务的发起者(决定了全局事务的开启,回滚,提交等) ***凡是我们的微服务中标注了@GlobalTransactional ,那么该微服务就会被看出 一个TM。我们业务场景中订单微服务就是一个事务发起者,同时也是一个RM
TC(全局事务的协调者):这里就是我们的Seata-server,用来保存全局事务,分支 事务,全局锁等记录,然后会通知各个RM进行回滚或者提交. 二:整体机制(两阶段提交协议的演变)
工作原理
执行业务SQL update product set name = 'GTS' where name = 'TXC';
第一阶段:
1:解析 SQL:得到 SQL 的类型(UPDATE),表(product),条件(where id= '1')等相关的信息。
2:查询前镜像:根据解析得到的条件信息,生成查询语句,定位数据。
select id, name, since from product where name = 'TXC';
3:执行业务 SQL:更新这条记录的 name 为 'GTS'。
update product set name = 'GTS' where name = 'TXC';
4:查询后镜像:根据前镜像的结果,通过 主键 定位数据
select id, name, since from product where id = 1`;
5:插入回滚日志:把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记 录,插入到 UNDO_LOG 表中。
{
"branchId": 641789253,
"undoItems": [{
"afterImage": {
"rows": [{
"fields": [{
"name": "id",
"type": 4,
"value": 1
}, {
"name": "name",
"type": 12,
"value": "GTS"
}, {
"name": "since",
"type": 12,
"value": "2014"
}]
}],
"tableName": "product"
},
"beforeImage": {
"rows": [{
"fields": [{
"name": "id",
"type": 4,
"value": 1
}, {
"name": "name",
"type": 12,
"value": "TXC"
}, {
"name": "since",
"type": 12,
"value": "2014"
}]
}],
"tableName": "product"
},
"sqlType": "UPDATE"
}],
"xid": "xid:xxx"
}
6:提交前,向 TC 注册分支:申请 product 表中,主键值等于 1 的记录的 全局 锁 。
7:本地事务提交:业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交。
8:将本地事务提交的结果上报给 TC。
二阶段-回滚
1:收到 TC 的分支回滚请求,开启一个本地事务,执行如下操作
2:通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。
3:数据校验:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数 据被当前全局事务之外的动作做了修改
4:根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句:
5:提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。
二阶段-提交
1:收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成 功的结果给 TC。
2:异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。
三:快速开始搭建Seata环境 3.1)Seata-server环境搭建
二、快速开始搭建Seata环境
1.Seata-server环境搭建
第一步:https://github.com/seata/seata/releases 下载seata-server包
第二步: 解压我们的下载包seata-server包,解压的路径结构
第三步: 进入conf目录下 拿到db_store.sql脚本 ,然后再本地数据库创建一个 seata的数据库,执行脚本db_store.sql。
第四步: 修改conf目录下的file.conf文件
修改的节点: service节点
service {
#vgroup‐>rgroup
//修改全局事务分组
vgroup_mapping.prex_tx_group = "default"
#only support single node
#seata‐server的连接地址
default.grouplist = "127.0.0.1:8091"
#degrade current not support
enableDegrade = false#disabledisable = false#unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
max.commit.retry.timeout = "‐1"
max.rollback.retry.timeout = "‐1"
}
修改store节点:
store {
## store mode: file、db
//存储模式 使用db
mode = "db"
file{//file的不要改}
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/Bas
icDataSource(dbcp) etc.
//数据源的类型
datasource = "druid"
## mysql/oracle/h2/oceanbase etc.
db‐type = "mysql"
driver‐class‐name = "com.mysql.jdbc.Driver"
//你seata库的地址
url = "jdbc:mysql://lcalhost:3306/seata"
user = "root"
password = "Zw726515"
min‐conn = 1
max‐conn = 3
global.table = "global_table"
branch.table = "branch_table"
lock‐table = "lock_table"
query‐limit = 100
}
第五步:修改conf目录下的register.conf文件
修改registry节点的type类型为nacos
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"nacos {
serverAddr = "localhost:8848"
namespace = ""
cluster = "default"
}。。。。。。。。。。。。}
修改config节点的type改为nacos
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"nacos {
serverAddr = "localhost:8848"
namespace = ""
cluster = "default"
}
。。。。。。
。。。。。。
}
第六步:修改conf文件下的nacos-config.txt文件
第六步: 使用git的控制台 执行sh脚本 sh nacos-config.sh localhost 把seata的配置导入到nacos的配置中心上去
第七步:启动 seata-server服务 进入seata的bin目录点击执行seata-server.bat
微服务搭建步骤
第一步:添加pom依赖
<!‐‐seata‐‐>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐alibaba‐seata</artifactId>
<exclusions>
<exclusion>
<artifactId>seata‐all</artifactId>
<groupId>io.seata</groupId>
</exclusion></exclusions></dependency><dependency><groupId>io.seata</groupId><artifactId>seata‐all</artifactId><version>${seata.version}</version></dependency>
第二步:写注解 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class Tulingvip06MsAlibabaOrderApplication {public static void main(String[] args) {
SpringApplication.run(Tulingvip06MsAlibabaOrderApplication.class, args);
}}
微服务发起者需要写全局事务注解(这里是order服务为发起者)
@GlobalTransactional(name = "prex-create-order",rollbackFor = Exception.class)
@GlobalTransactional(name = "prex‐create‐order",rollbackFor =
Exception.class)
@Override
public void createOrder(Order order) {
log.info("当前 XID: {}", RootContext.getXID());
log.info("下单开始,用户:{},商品:{},数量:{},金额:{}", order.getUserId(),
order.getProductId(), order.getCount(), order.getPayMoney());
//创建订单
order.setStatus(0);
orderMapper.saveOrder(order);
log.info("保存订单{}", order);//远程调用库存服务扣减库存log.info("扣减库存开始");remoteStorageService.reduceCount(order.getProductId(), order.getCount());log.info("扣减库存结束");//远程调用账户服务扣减余额log.info("扣减余额开始");remoteAccountService.reduceBalance(order.getUserId(), order.getPayMoney());log.info("扣减余额结束");//修改订单状态为已完成log.info("修改订单状态开始");orderMapper.updateOrderStatusById(order.getId(),1);log.info("修改订单状态结束");log.info("下单结束");}
第三步:写配置添加代理数据源配置
@Configuration
@MapperScan(basePackages = {"com.demo.seata.mapper"})
public class MyBatisConfig {/**
* 从配置文件获取属性构造datasource,注意前缀,这里用的是hikari,根据自己情况配置,
* 原生datasource前缀取"spring.datasource"
** @return*/@Bean@ConfigurationProperties(prefix = "spring.datasource.hikari")public DataSource hikariDataSource() {return new HikariDataSource();}/*** 构造datasource代理对象,替换原来的datasource** @param hikariDataSource* @return*/@Primary@Bean("dataSource")public DataSourceProxy dataSourceProxy(DataSource hikariDataSource) {return new DataSourceProxy(hikariDataSource);}@Beanpublic SqlSessionFactoryBean sqlSessionFactory(DataSourceProxy dataSourcePr
oxy) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternRes
olver()
.getResources("classpath:/mybatis/mapper/**/*.xml"));
sqlSessionFactoryBean.setConfigLocation(new PathMatchingResourcePatternReso
lver().getResource("classpath:/mybatis/mybatis‐config.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("com.tuling.seata.domin");
sqlSessionFactoryBean.setDataSource(dataSourceProxy);
return sqlSessionFactoryBean;
}}
第四步:修改配置文件 yml中添加配置文件
#seata配置(配置事务组 需要和seata‐server的配置一样)
spring.cloud.alibaba.seata.tx‐service‐group=prex_tx_group
修改file.conf 和register.conf文件(跟seata-server的改动一样)
4:微服务测试
http://localhost:8081/order/create?userId=1&productId=1&count=1&payMoney=50
4.1)正常情况
库存库
4.2)异常情况,我们把支付服务人工模拟抛出异常。
库存库:
微服务分布式事务解决方案Seata相关推荐
- seata xid是什么_微服务分布式事务解决方案-springboot整合分布式seata1.3.0
概述 Seat是蚂蚁金服和阿里巴巴联合推出的一个开源的分布式事务框架,在阿里云商用的叫做GTS. 项目地址:https://github.com/longxiaonan/springcloud-dem ...
- 微服务 分布式事务解决方案
一. 前言 阿里2017云栖大会<破解世界性技术难题!GTS让分布式事务简单高效>中,阿里声称提出了一种破解世界性难题之分布式事务的终极解决方案,无论是可靠性.还是处理速率都领先于市面上所 ...
- 分布式事务解决方案Seata
一.Seata 简介 Seata 是 阿里巴巴2019年开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务.在 Seata 开源之前,Seata 对应的内部版本在阿里内 ...
- 一行代码就能解决微服务分布式事务问题,你知道GTS怎么做到的吗?
2019独角兽企业重金招聘Python工程师标准>>> GTS直播火热报名中,直播直通车 一.GTS (Global Transaction Service)是啥? GTS(全局事务 ...
- seata 如何开启tcc事物_微服务分布式事务4种解决方案实战
分布式事务 分布式事务是指事务的参与者,支持事务的服务器,资源服务器分别位于分布式系统的不同节点之上,通常一个分布式 事物中会涉及到对多个数据源或业务系统的操作. 典型的分布式事务场景:跨银行转操作就 ...
- 同事操作两个数据源保持事务一致_微服务分布式事务4种解决方案实战
分布式事务 分布式事务是指事务的参与者,支持事务的服务器,资源服务器分别位于分布式系统的不同节点之上,通常一个分布式 事物中会涉及到对多个数据源或业务系统的操作. 典型的分布式事务场景:跨银行转操作就 ...
- 微服务-分布式事务seata
什么是分布式事务 单体应用被拆分成微服务应用,原来的三个模块被拆分成三个独立的应用,分别使用三个独立的数据源, 业务操作需要调用三个服务来完成.此时每个服务内部的数据一致性由本地事务来保证,但是全局的 ...
- druid seata 配置_分布式事务解决方案——Seata使用
在微服务开发过程中分布式事务一直是一个比较重要的问题,之前对于分布式事务的解决方法一般会通过MQ的最终一致性来解决,尤其是RocketMQ的事务消息,感兴趣的可以看Spring Boot整合Rocke ...
- seata 集群_【视频】 聊聊分布式事务解决方案seata
什么seata Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务.在 Seata 开源之前,Seata 对应的内部版本在阿里经济体内部一直扮演着分布 ...
最新文章
- 靠数学“拿了”两次诺贝尔奖,彭罗斯从“铺地砖”帮忙发现2011年化学奖的秘密...
- python游戏中调整箭头下落速度_入门 | 三行Python代码,让数据预处理速度提高2到6倍...
- Centos7 安装 docker-ce
- 第16/24周 SQL Server 2014中的基数计算
- Linux中ACL权限设置
- 【Android】15.0 第15章 广播和通知—本章示例主界面
- 设置窗体的可见性无效
- C++关键字 friend
- maya 处理 linux 鼠标变X
- 星空连线html5,js canvas实现星空连线背景特效
- MSDN下载的win7 32位原版镜像无法安装vmtools和提示安装程序无法自动安装Virtual Machine Communication Interface(VMCI)驱动程序
- Redis客户端工具安装
- MathType软件安装教程及下载地址
- keepalived 健康检查机制说明
- unity游戏开发之打包apk谷歌上架报错总结
- Excel技能树系列02:公式中单元格的绝对引用、相对引用和混合引用
- JVM 上篇(4):虚拟机栈
- OE(OSA)期刊模板下载
- 【科创人】瑞云创始人汪忠田:售后服务SaaS市场拓荒者
- nginx日志[配置解释]
热门文章
- 戴着面具的复仇者 —— 揭秘:激进黑客组织“匿名者
- HTML5期末大作业:个人信息展示网站设计——清新春暖花开个人博客网站(6页) HTML+CSS+JavaScript...
- SRA-Toolkit使用方法
- 经典算法之汉诺塔求解问题
- gitee创建仓库方法
- Java周末班脱产班_急:java培训上周末班还是脱产班?
- 计算机组成原理COP2000课设 原码一位乘
- 《代码大全2》第10章 使用变量的一般事项
- MySQL 数据备份与恢复(小学生篇)
- HTML小游戏24 —— h5魂斗罗之突围游戏(附完整源码)