第五章 Seata事务框架笔记

一、Seata概念介绍

1、Seata 是什么?

Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA和XA事务模式,为用户打造一站式的分布式解决方案。

seata下载http://seata.io/en-us/blog/download.html

选择自己的版本下载

seat中文文档:http://seata.io/zh-cn/docs/overview/what-is-seata.html

这里我们只介绍默认的AT模式与TCC模式。

2、Seata默认的AT模式介绍

前提

基于支持本地ACID事务的关系型数据库。

Java应用,通过JDBC访问数据库。

整体机制

两阶段提交协议的演变:

一阶段:

业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。

二阶段:

提交异步化,非常快速地完成。

回滚通过一阶段的回滚日志进行反向补偿。

写隔离

一阶段本地事务提交前,需要确保先拿到全局锁。拿不到全局锁,不能提交本地事务。拿全局锁的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。以一个示例来说明:

两个全局事务tx1和tx2,分别对a表的m字段进行更新操作,m的初始值1000。

tx1先开始,开启本地事务,拿到本地锁,更新操作m = 1000 - 100 = 900。本地事务提交前,先拿到该记录的全局锁,本地提交释放本地锁。tx2后开始,开启本地事务,拿到本地锁,更新操作m = 900 - 100 = 800。本地事务提交前,尝试拿该记录的全局锁,tx1全局提交前,该记录的全局锁被tx1持有,tx2需要重试等待全局锁。

tx1二阶段全局提交,释放全局锁 。tx2拿到全局锁 提交本地事务。

如果tx1的二阶段全局回滚,则tx1需要重新获取该数据的本地锁,进行反向补偿的更新操作,实现分支的回滚。

此时,如果tx2仍在等待该数据的全局锁,同时持有本地锁,则tx1的分支回滚会失败。分支的回滚会一直重试,直到tx2的全局锁等锁超时,放弃全局锁并回滚本地事务释放本地锁,tx1的分支回滚最终成功。

因为整个过程全局锁在tx1结束前一直是被tx1持有的,所以不会发生脏写的问题。

读隔离

在数据库本地事务隔离级别读已提交(Read Committed)或以上的基础上,Seata(AT 模式)的默认全局隔离级别是读未提交(Read Uncommitted)。

如果应用在特定场景下,必需要求全局的读已提交 ,目前Seata的方式是通过SELECT FOR UPDATE语句的代理。

SELECT FOR UPDATE语句的执行会申请全局锁 ,如果 全局锁被其他事务持有,则释放本地锁(回滚 SELECT FOR UPDATE语句的本地执行)并重试。这个过程中,查询是被block住的,直到 全局锁拿到,即读取的相关数据是 已提交 的,才返回。

出于总体性能上的考虑,Seata目前的方案并没有对所有SELECT语句都进行代理,仅针对FOR UPDATE 的SELECT语句。

3、TCC模式

回顾总览中的描述:一个分布式的全局事务,整体是两阶段提交的模型。全局事务是由若干分支事务组成的,分支事务要满足两阶段提交的模型要求,即需要每个分支事务都具备自己的:

  • 一阶段prepare行为
  • 二阶段commit或rollback行为

根据两阶段行为模式的不同,我们将分支事务划分为Automatic (Branch) Transaction Mode和Manual (Branch) Transaction Mode。

AT模式基于支持本地ACID事务的关系型数据库:

  • 一阶段prepare行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
  • 二阶段commit行为:马上成功结束,自动异步批量清理回滚日志。
  • 二阶段rollback行为:通过回滚日志,自动生成补偿操作,完成数据回滚。

相应的TCC模式,不依赖于底层数据资源的事务支持:

  • 一阶段prepare行为:调用自定义的prepare逻辑。
  • 二阶段commit行为:调用自定义的commit逻辑。
  • 二阶段rollback行为:调用自定义的rollback逻辑。

所谓TCC模式,是指支持把自定义的分支事务纳入到全局事务的管理中。

二、seata服务端与nacos整合开发

1、配置seata的服务器端的数据库

https://github.com/seata/seata/tree/1.2.0/script

server端脚本如下,同时也支持docker、kubernatesa安装

 

1)全局事务会话信息由3块内容构成,全局事务-->分支事务-->全局锁,对应表global_table、branch_table、lock_table 1;建立一个数据库名字随意用来做seata服务端的库,存储全局事务的会话信息

2)拿到服务端数据库的脚本文件执行并且建立表第1步三张表

https://github.com/seata/seata/tree/1.2.0/script/server/db 上面地址可以拿到数据库脚本,选择mysql然后自己执行。

2、修改服务端启动包的文件

1)启动包: seata-->conf-->file.conf,修改store.mode="db"。

2)修改file.conf自己的db连接信息

## transaction log store, only used in seata-server
store {
  ## store mode: file、db
  mode = "db"
  ## database store property
  db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
    datasource = "druid"
    ## mysql/oracle/postgresql/h2/oceanbase etc.
    dbType = "mysql"
    driverClassName = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://localhost:3306/seata?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true"
    user = "root"
    password = "root"
    minConn = 5
    maxConn = 1000
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000
  }
}

这些信息是存在file.conf当中的也就是seata启动的时候会去读取这个配置文件;如果我们使用nacos可以把这些信息放到nacos的注册中心,从而实现动态更新。

如果你需要把这些信息放到nacos配置中心就需要修改seata-->conf-->registy.conf文件当中的注册中心和配置中心的信息,修改成为nacos;(为什么需要修改config和register呢?因为如果你的seata服务器想要去配置中心读取配置,那么一定到得把自己注册到nacos;所以registy.conf当中需要配置注册中心的地址也需要配置配置中心的地址) 这样我们如果后面启动seata就可以看到他是作为了一个nacos的客户端注册到了nacos的注册中心的;记住这点seata已经可以作为客户端注册到nacos了。

3、Seata部署指南

Seata分TC、TM和RM三个角色,TC(Server端)为单独服务端部署,TM和RM(Client端)由业务系统集成。

资源目录介绍:https://github.com/seata/seata/tree/1.2.0/script

Client:存放client端sql脚本,参数配置。

config-center:各个配置中心参数导入脚本,config.txt(包含server和client,原名nacos-config.txt)为通用参数文件。

Server:server端数据库脚本及各个容器配置。

注意事项

seata-spring-boot-starter

内置GlobalTransactionScanner自动初始化功能,若外部实现初始化,请参考SeataAutoConfiguration保证依赖加载顺序

默认开启数据源自动代理,可配置seata.enable-auto-data-source-proxy: false关闭

spring-cloud-alibaba-seata

查看版本说明 2.1.0内嵌seata-all 0.7.1,2.1.1内嵌seata-all 0.9.0,2.2.0内嵌seata-spring-boot-starter 1.0.0

2.1.0和2.1.1兼容starter解决方案:

2.1.0和2.1.1兼容starter解决方案: @SpringBootApplication注解内exclude掉spring-cloud-alibaba-seata内的com.alibaba.cloud.seata.GlobalTransactionAutoConfiguration

3、把配置信息上传到nacos配置中心

第一步:启动nacos

第二步:访问https://github.com/seata/seata/tree/1.2.0/script/config-center到这个地址上面获取config.txt,然后把config.txt复制到idea当中去编辑,推荐使用idea编辑,因为可能有编码原因,保留自己想要的信息。

这里给出的是精简后的,你们需要自己对应修改自己的信息;主要是数据库配置信息。注意这些信息是服务器端和客户端都要使用的;由于上面我们已经把seata注册到了nacos;所以他的file.conf当中的信息可以直接从nacos读取;也就是下面我们配置的信息;换句话说如果你配置了seata作为nacos的一个客户端去读取配置那么file.conf可以不用配置了;这两步是重复的;这也是网上很多资料没有说明的;换成大白话的意思就是你如果配置了registy.conf那么file.conf当中的信息基本无效——都是从配置中心读取;甚至可以删了file.conf;你们可以自己测试;如果你不配置registy.conf,那么seata就会从file.conf当中读取配置;所以file.conf和registy.conf其实只需要配置一个。

3.1、精简后的配置如下

#事务分组——my_test_tx_group 这值会在我们客户端对应,需要注意
service.vgroupMapping.my_test_tx_group=default
service.default.grouplist=127.0.0.1:8091
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://ip::3306/seata?useUnicode=true
store.db.user=root
store.db.password=root
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000

那么这些精简后的配置如何传到nacos呢?

https://github.com/seata/seata/tree/1.2.0/script/config-center 从上面这个地址下载nacos文件下面的nacos-config.sh文件然后执行sh 你下载后的路径/nacos-config.sh;当然如果你的nacos地址不是默认的,需要修改naocs-config.sh当中指定你的路径;也可以在sh命令后面指定;

 https://github.com/seata/seata/tree/1.2.0/script/config-center这个地址里面有个README.md文件有说明。

3.2、Nacos执行shell命令配置:

bash
sh ${SEATAPATH}/script/config-center/nacos/nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t namespace

参数说明:

-h: host, the default value is localhost

-p: port, the default value is 8848

-g: Configure grouping, the default value is 'SEATA_GROUP'

-t: Tenant information, corresponding to the namespace ID field of Nacos, the default value is ''

注意:

这里我们在Nacos配置里面创建一个namespace叫seata,ID为seata_id

3.3、cd到Nacos文件夹所在目录执行命令:

sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t seata_id

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值