08_Seata—分布式事务介绍

Seata—分布式事务介绍

事务ACID

Seata就是解决这两种分布式事务的场景的

在这里插入图片描述

Seata—什么是Seata

Sea是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务,Seata将为用户提供了AT、TCC、SAGA和XA事务模式,为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本的GTS(Global Transaction Service 全局事务服务)

Seata—二阶段提交协议

1.seata阿里分布式事务框架

2.消息队列

3.saga

4.XA

他们有一个共同点,都是"两阶段(2PC)"。"两阶段"是指完成整个分布式事务,划分成两个步骤完成。实际上,这四种常见的分布式事务廨决方案,分别对应着分布式事务的四种模式: AT、TCC、Saga、XA;

2PC两阶段提交协议(Two-Phase Commit):

顾名思义分为两个阶段 Prepare 和 Commit

Prepare : 提交事务请求

基本流程如下图:

在这里插入图片描述

1.询问 协调者向所有参与者发送事务请求,询问是否可执行事务操作,然后等待各个参与者的响应。
⒉执行 各个参与者接收到协调者事务请求后,执行事务操作(例如更新一个关系型数据库表中的记录),并将Undo和Redo信息记录事务日志中。
3 响应 如果参与者成功执行了事务并写入Undo和Redo信息,则向协调者返回YES响应,否则返回NO响应。当然,参与者可能宕机,从而不会返回响应

Commit: 执行事务提交

基本流程如下图:

在这里插入图片描述

  1. commit 请求协调者向所有参与者发送Commit 请求。
  2. 事务提交参与者收到Commit 请求后,执行事务提交,提交完成后释放事务执行期占用的所有资源。
  3. 反馈结果参与者执行事务提交后向协调者发送Ack响应。
  4. 完成事务接收到所有参与者的Ack 响应后,完成事务提交。

中断事务

在执行Prepare步骤过程中,如果某些参与者执行事务失败、宕机或与协调者之间的网络中断,那么协调者就无法收到所有参与者的YES响应,或者某个参与者返回了No响应.此时,协调者就会进入回退流程,对事务进行回退。流程如下图红色部分(将Commit 请求替换为红色的Rollback 请求):

在这里插入图片描述

  1. rollback请求协调者向所有参与者发送Rollback 请求。
  2. 事务回滚参与者收到Rollback 后,使用Prepare阶段的Undo日志执行事务回滚,完成后释放事务执行期占用的所有资源。
  3. 反馈结果参与者执行事务回滚后向协调者发送Ack 响应。
  4. 中断事务接收到所有参与者的Ack 响应后,完成事务中断。

在这里插入图片描述

2PC的问题

1.同步阻塞

2.单点故障

3.数据不一致

4.环境可靠性依赖性

Seata—分布式解决方案:AT模式

AT模式 : auto transcation(主推)

AT模式是—种无侵入的分布式事务解决方案,

阿里seata框架,实现了该模式。

在AT模式下,用户只需关注自己的"业务SQL",用户的“业务SQL"作为一阶段,Seata框架会自动生成事务的二阶段提交和回滚操作。

在这里插入图片描述

AT模式如何做到对业务的无侵入∶

  • 一阶段 :

在一阶段,Seata 会拦截“业务SQL”,首先解析SQL语义,找到“业务SQL"要更新的业务数据,在业务数据被更新前,将其保存成"before image,然后执行业务SQL"更新业务数据,在业务数据更新之后,再将其保存成"after image’,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。

在这里插入图片描述

在这里插入图片描述

  • 二阶段提交:

二阶段如果是提交的话,因为"业务SQL"在一阶段已经提交至数据库,所以Seata框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可.

在这里插入图片描述

  • 二阶段回滚:

二阶段如果是回滚的话,Seata就需要回滚一阶段已经执行的M业务SQL",还原业务数据。回滚方式便是用"before image"还原业务数据;但在还原前要首先要校验脏写,对比"数据库当前业务数据"和"after image,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。

在这里插入图片描述

Seata—分布式解决方案:TCC模式

tcc == try confirm cancel

TCC模式需要用户根据自己的业务场景实现Ty、Confim和Cancel三个操作;事务发起方在一阶段执行Try 方式,在二阶段提交执行Confirm方法,二阶段回滚执行Cancel方法。

优点 : 在整个过程基本没有锁,性能更强

缺点 : 侵入性比较强,并且得自己实现相关事务控制逻辑

在这里插入图片描述

可靠消息最终一致性方案

在这里插入图片描述

Seata—Seate的AT模式原理

在Seata的架构中,一共有三个角色:
Tc (Transaction Coordinator)-事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。

TM(Transaction Manager)-事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。

RM(Resource Manager)-资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

其中,TC为单独部署的Server服务端,TM和RM为嵌入到应用中的 Client客户端。

第一阶段

在这里插入图片描述

第二阶段

分布式事务操作成功,则TC通知RM异步删除undolog

在这里插入图片描述

分布式事务操作失败,TM向TC发送回滚请求,RM收到协调器TC发来的回滚请求,通过XID和Branch lD找到相应的回滚日志记录,通过回滚记录生成反向的更新SQL并执行,以完成分支的回滚。

在这里插入图片描述

Seata—服务搭建—db数据源

Seata Server(TC)环境搭建

下载地址 https://github.com/seata/seata/releases

2.2.5对应1.3.0 下载1.3.0版本 后解压

Server端存储模式(store.mode)支持三种:

  • file:(默认)单机模式,全局事务会话信息内存中读写并持久化本地文件root.data,性能较高(默认)
  • db:高可用模式 , 全局事务会话信息通过db共享,相应性能差些
  • redis: Seata-Server 1.3及以上版本支持,性能较高,存在事务信息丢失风险,.请提前配置适合当前场景的redis持久化配置

1.打开conf/file.conf

第3-5行中 修改

mode="file"  修改成  mode="db"

在这里插入图片描述

修改数据源

在这里插入图片描述

2.创建数据库seata_server

数据库语句 https://github.com/seata/seata/tree/1.4.0/script/server/db

运行mysql.sql后有这三张表

在这里插入图片描述

Seata—服务搭建—nacos

db+Nacos得方式部署高可用集群模式

先启动 Nacos

1.修改seata/conf/registry.conf

type = 'file    修改成    'type = 'nacos'

# 除了nacos 下面的配置去掉

在这里插入图片描述

修改下面的config(也是在seata/conf/registry.conf里面)

在这里插入图片描述

修改script/config-center/config.txt

store.mode改成db 下面选中删掉

在这里插入图片描述

再修改下面的数据源

在这里插入图片描述

事务分组:异地机房停电容错机制

my_test_tx_group 可以自定义 比如:(guangzhou,shanghai…),对应的client也要去设置

这边的default 必须要等于 registry.conf cluster = “default”

在这里插入图片描述

运行script/config-center/nacos 下的 nacos-config.sh 就可以将config.txt注册到nacos中心因为是本机127.0.0.1所以可以直接注册

运行结束后nacos配置列表多了很多规则

nacos中效果

在这里插入图片描述

自定义 ---- shell(git bash):

sh $[SEATAPAR)/script/config-certer/nacos/nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 5a3c7d6c-f497-4d68-71a-2e5e3340b3ca

-h: host,默认值localhost

-p: port,默认值8848

-g: 配置分组,默认值为’SEATA_GROUP’

-t: 租户信息,对应 Nacos的命名空间ID字段,默认值为空"

然后就可以运行 seata/bin/seata-server.bat了 端口是8091

发现报错

我们缺少logs文件夹下的seata_gc.log

我们在bin目录的同级目录下创建logs目录,在logs目录下创建seata_gc.log,需要注意的一点是要把seata_gc.log文件的其他后缀都去掉,只要seata_gc.log


又发现问题 数据库driverClassName 要用com.mysql.cj.jdbc.Driver
(我的数据库是8.0)
然后保存启动seata

启动成功 nacos中查看服务列表多了一个服务

在这里插入图片描述

(linux集群)更改端口

bin/seata-server.sh  -p  8092   -n 1 
bin/seata-server.sh  -p  8093   -n 2
bin/seata-server.sh  -p  8094   -n 3 

Seata—分布式事务代码搭建

声明式事务实现 (@GlobalTransactional)

基础环境

在这里插入图片描述

order-seata模块

controller层

在这里插入图片描述

service层

在这里插入图片描述

思考 用@Transactional注解处理 如果抛出异常会怎样

答 insert方法回滚 但远程服务就不会回滚

stock-seata模块

controller层

在这里插入图片描述

service层

在这里插入图片描述

访问 /order/add 页面显示报错

现象 order没有插入 但stock减库存了

本地@Transactional注解是没有办法解决分布式事务的场景

Seata—Client搭建

1.添加依赖(stock-seata模块和order-seata模块)

<!--seata的依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

2.各(两个数据库)服务对应数据库中添加undo_log表

create table `undo_log`(
    `id` bigint(20) not null auto_increment,
    `brand_id` bigint(20) not null,
    `xid` varchar(100) not null,
    `context` varchar(128) not null,
    `rollback_info` longblob not null,
    `log_status` int(11) not null,
    `log_created` datetime not null,
    `log_modified` datetime not null,
    primary key(`id`),
    unique key `ux_undo_log` (`xid`,`brand_id`)
)engine=InnoDB auto_increment=1 default charset = utf8;

3.配置文件(两个模块)

#而皮质事务分组
spring:
  cloud:
    alibaba:
       seata:
          tx-service-group: my_test_tx_group #对应配置文件中的名字


seata:
  registry:
    #配置seata的注册中心,告诉seata client怎么去访问seata server
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848 #seata server 所在的nacos服务地址
      application: seata-server   # seata server 的服务名,默认就是seata-server,没有改可以不配
      username: nacos
      password: nacos
      group: SEATA_GROUP  # seata server 所在的组,默认就是SEATA_GROUP,没有改可以不配
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      username: nacos
      password: nacos
      group: SEATA_GROUP

在这里插入图片描述

4.更改注解

将之前的 @Transactional 注解改成 @GlobalTransactional 注解

5.测试访问

访问 /order/add 页面显示报错

现象 order没有插入 stock减库也没有减

说明都回滚了 成功!

思考 配置中心那么多有什么用

就是为了读取我们之前的配置 db、数据库这种我们之前自定义的配置

Seata—运行原理总结

在这里插入图片描述

1.TM请求TC开启一个全局事务。 TC会生成一个XID作为该全局事务的编号。 XID,会在微服务的调用链路中传播,保证将多个微服务的子事务关联在一起.

(当一进入事务方法中就会生成XID global_table)

2.RM请求TC将本地事务注册为全局事务的分支事务,通过全局事务的XID进行关联。

(当运行数据库操作方法 branch_table 存储事务参与者)

3.TM请求TC告诉XID对应的全局事务是进行提交还是回滚。

4.TC驱动RM们将XID对应的自己的本地事务进行提交还是回滚。

在插入订单那打个断点 发现global_table生成一条数据,就是全局事务的信息(包括XID)

每一个@GlobalTransactional 注解在都会在global_table生成一条全局事务的信息

在这里插入图片描述

branch_table 存储事务参与者

lock_table 锁表

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值