Spring Cloud Alibaba分布式事务组件 seata 详解(小白都能看懂)
一,什么是事务(本地事务)?
指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
简单的说,事务就是并发控制的单位,是用户定义的一个操作序列。
而一个逻辑工作单元要成为事务,就必须满足ACID属性。
A:原子性(Atomicity)
事务中的操作要么都不做,要么就全做。
C:一致性(Consistency)
事务执行的结果必须是从数据库从一个一致性状态转换到另一个一致性状态。
I:隔离性(Isolation)
一个事务的执行不能被其他事务干扰
D:持久性(Durability)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
注:如果对事务不是很懂可以参考这篇文章:什么是事务?事务的四个特性以及事务的隔离级别 - Kevin.ZhangCG - 博客园 (cnblogs.com)
二, 分布式事务
随着互联网的快速发展,软件系统由原来的单体应用转变为分布式应用,下图描述了单体应用向微服务的演变:

分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务。
三,分布式事务产生的情景
- 跨JVM进程产生分布式事务
典型的场景就是微服务架构:微服务之间通过远程调用完成事务操作。比如:订单微服务和库存微服务,下单的同时订单微服务请求库存微服务减少库存。

- 跨数据库实例产生分布式事务
单体系统访问多个数据库实例当单体系统需要访问多个数据库(实例)时就会产生分布式事务。比如:用户信息和订单信息分别在两个MySQL实例存储,用户管理系统删除用户信息,需要分别删除用户信息及用户的订单信息,由于数据分布在不同的数据实例,需要通过不同的数据库链接去操作数据,此时产生分布式事务。

- 多服务访问同一个数据库实例
订单微服务和库存微服务即使访问同一个数据库也会产生分布式事务,原因就是跨JVM进程,两个微服务持有了不同的数据库链接进行数据库操作,此时产生分布式事务。

四, 分布式事务解决方案之 2PC
常见分布式事务解决方案:
1.seata 阿里分布式事务框架
2. 消息队列
3.sage
4,XA
但是他们都有一个共同点:都是两个阶段(2PC)。其实这四种解决方案对应的是分布式事务的四种模式:AT,TCC,Sage,XA
4.1 什么是 2PC
2PC 即两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段(Prepare phase)、提交阶段(commit phase),2 是指两个阶段,P 是指准备阶段,C 是指提交阶段。
举例:张三和李四好久不见,老友约起聚餐,饭店老板要求先买单,才能出票。这时张三和李四分别抱怨近况不如意,囊中羞涩,都不愿意请客,这时只能AA。只有张三和李四都付款,老板才能出票安排就餐。但由于张三和李四都是铁公鸡,形成了尴尬的一幕:
准备阶段:老板要求张三付款,张三付款。老板要求李四付款,李四付款。
提交阶段:老板出票,两人拿票纷纷落座就餐。
例子中形成了一个事务,若张三或李四其中一人拒绝付款,或钱不够,店老板都不会给出票,并且会把已收款退回。
整个事务过程由事务管理器和参与者组成,店老板就是事务管理器,张三、李四就是事务参与者,事务管理器负责决策整个分布式事务的提交和回滚,事务参与者负责自己本地事务的提交和回滚。
在计算机中部分关系数据库如 Oracle、MySQL 支持两阶段提交协议,如下图:
- 准备阶段(Prepare phase):事务管理器给每个参与者发送 Prepare 消息,每个数据库参与者在本地执行事务,并写本地的 Undo/Redo 日志,此时事务没有提交。(Undo 日志是记录修改前的数据,用于数据库回滚,Redo 日志是记录修改后的数据,用于提交事务后写入数据文件)
- 提交阶段(commit phase):如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。注意:必须在最后阶段释放锁资源。
下图展示了2PC的两个阶段,分成功和失败两个情况说明:
成功情况

失败情况

五,Seata 方案(AT模式)
Seata 是由阿里中间件团队发起的开源项目 Fescar,后更名为 Seata,它是一个是开源的分布式事务框架。
传统 2PC 的问题在 Seata 中得到了解决,它通过对本地关系数据库的分支事务的协调来驱动完成全局事务,是工作在应用层的中间件。主要优点是性能较好,且不长时间占用连接资源,它以高效并且对业务 0 侵入的方式解决微服务场景下面临的分布式事务问题,它目前提供 AT 模式(即 2PC)及 TCC 模式的分布式事务解决方案。
Seata 的设计思想如下:
Seata 的设计目标其一是对业务无侵入,因此从业务无侵入的 2PC 方案着手,在传统 2PC的基础上演进,并解决 2PC 方案面临的问题。
Seata 把一个分布式事务理解成一个包含了若干分支事务的全局事务。全局事务的职责是协调其下管辖的分支事务达成一致,要么一起成功提交,要么一起失败回滚。此外,通常分支事务本身就是一个关系数据库的本地事务,下图是全局事务与分支事务的关系图:

与传统 2PC 的模型类似,Seata 定义了 3 个组件来协议分布式事务的处理过程:

- Transaction Coordinator(TC):事务协调器,它是独立的中间件,需要独立部署运行,它维护全局事务的运行状态,接收 TM 指令发起全局事务的提交与回滚,负责与 RM 通信协调各各分支事务的提交或回滚。
- Transaction Manager(TM): 事务管理器,TM 需要嵌入应用程序中工作,它负责开启一个全局事务,并最终向 TC 发起全局提交或全局回滚的指令。
- Resource Manager(RM):控制分支事务,负责分支注册、状态汇报,并接收事务协调器 TC 的指令,驱动分支(本地)事务的提交和回滚。
举例Seata的分布式事务过程:
简单业务逻辑图:

第一阶段:

第二阶段:提交,回滚
提交:
回滚:

Seata实现2PC与传统2PC的差别
架构层次方面:传统 2PC 方案的 RM 实际上是在数据库层,RM 本质上就是数据库自身,通过 XA 协议实现,而 Seata 的 RM 是以 jar 包的形式作为中间件层部署在应用程序这一侧的。
两阶段提交方面:传统 2PC无论第二阶段的决议是 commit 还是 rollback ,事务性资源的锁都要保持到 Phase2 完成才释放。而 Seata 的做法是在 Phase1 就将本地事务提交,这样就可以省去 Phase2 持锁的时间,整体提高效率。
六,TCC模式
缺点:代码侵入性较强,需要自己手写处理代码
优点:没有锁的概念,效率高一点,由于是自己手写,定制化程度比较高。
Tcc 框架:
概念图:

简单业务图:

七,Seata 服务端的自带表说明
UNDO_LOG(回滚日志)表:记录参与者的xid和相关的操作,用于对事务的回滚
表结构:
`CREATE TABLE `undo_log` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `branch_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`,`branch_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
在 db 模式下,我们需要针对全局事务的会话信息创建以下 3 张数据库表。
全局事务表,对应的表为:global_table
分支事务表,对应的表为:branch_table
全局锁表,对应的表为:lock_table
---数据库server 要的表 -- -------------------------------- The script used when storeMode is 'db' -------------------------------- -- the table to store GlobalSession data CREATE TABLE IF NOT EXISTS "global_table" ( `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `status` TINYINT NOT NULL, `application_id` VARCHAR(32), `transaction_service_group` VARCHAR(32), `transaction_name` VARCHAR(128), `timeout` INT, `begin_time` BIGINT, `application_data` VARCHAR(2000), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`xid`), KEY `idx_status_gmt_modified` (`status` , `gmt_modified`), KEY `idx_transaction_id` (`transaction_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; -- the table to store BranchSession data CREATE TABLE IF NOT EXISTS `branch_table` ( `branch_id` BIGINT NOT NULL, `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `resource_group_id` VARCHAR(32), `resource_id` VARCHAR(256), `branch_type` VARCHAR(8), `status` TINYINT, `client_id` VARCHAR(64), `application_data` VARCHAR(2000), `gmt_create` DATETIME(6), `gmt_modified` DATETIME(6), PRIMARY KEY (`branch_id`), KEY `idx_xid` (`xid`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; -- the table to store lock data CREATE TABLE IF NOT EXISTS `lock_table` ( `row_key` VARCHAR(128) NOT NULL, `xid` VARCHAR(128), `transaction_id` BIGINT, `branch_id` BIGINT NOT NULL, `resource_id` VARCHAR(256), `table_name` VARCHAR(32), `pk` VARCHAR(36), `status` TINYINT NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking', `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`row_key`), KEY `idx_status` (`status`), KEY `idx_branch_id` (`branch_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; CREATE TABLE IF NOT EXISTS `distributed_lock` ( `lock_key` CHAR(20) NOT NULL, `lock_value` VARCHAR(20) NOT NULL, `expire` BIGINT, primary key (`lock_key`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
注:看到这里了,感觉有用,就关注一下吧,或者赞助一下吧!你们的赞助就是我创作的最大动力。
Spring Cloud Alibaba分布式事务组件 seata 详解(小白都能看懂)的更多相关文章
- 搭建分布式事务组件 seata 的Server 端和Client 端详解(小白都能看懂)
一,server 端的存储模式为:Server 端 存 储 模 式 (store-mode) 支 持 三 种 : file: ( 默 认 ) 单 机 模 式 , 全 局 事 务 会 话 信 息 内 存 ...
- Spring Cloud Alibaba 初体验(六) Seata 及结合 MyBatis 与 MyBatis-Plus 的使用
一.下载与运行 本文使用 Seata 1.1.0:https://github.com/seata/seata/releases Windows 环境下双击 bin/seata-server.bat ...
- Spring Cloud内置的Zuul过滤器详解
Spring Cloud默认为Zuul编写并启用了一些过滤器,这些过滤器有什么作用呢?我们不妨按照@EnableZuulServer.@EnableZuulProxy两个注解进行展开,相信大家对这两个 ...
- spring的annotation-driven配置事务管理器详解
http://blog.sina.com.cn/s/blog_8f61307b0100ynfb.html ——————————————————————————————————————————————— ...
- 小白都能看懂的Spring源码揭秘之IOC容器源码分析
目录 前言 IOC 只是一个 Map 集合 IOC 三大核心接口 IOC 初始化三大步骤 定位 加载 注册 总结 前言 在 Spring 框架中,大家耳熟能详的无非就是 IOC,DI,Spring M ...
- 小白都能看懂的 Spring 源码揭秘之Spring MVC
目录 前言 Spring MVC 请求流程 Spring MVC 两大阶段 初始化 HttpServletBean#init() FrameworkServlet#initServletBean Fr ...
- 小白都能看懂的 Spring 源码揭秘之依赖注入(DI)源码分析
目录 前言 依赖注入的入口方法 依赖注入流程分析 AbstractBeanFactory#getBean AbstractBeanFactory#doGetBean AbstractAutowireC ...
- Spring Cloud Alibaba 新一代微服务解决方案
本篇是「跟我学 Spring Cloud Alibaba」系列的第一篇, 每期文章会在公众号「架构进化论」进行首发更新,欢迎关注. 1.Spring Cloud Alibaba 是什么 Spring ...
- Spring Cloud Alibaba 教程 | 前世今生
Spring Cloud Alibaba是什么 先来看一下官方是怎么定义Spring Cloud Alibaba的: Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案.此 ...
随机推荐
- HMS Core机器学习服务助力Zaful用户便捷购物
Zaful是近年来发展良好的出海电商平台,主打快时尚.在洞察其用户有购买街头海报.生活中同款衣物的需求后,Zaful联合HMS Core机器学习服务打造拍照购物服务.用户拍照后可在预设的商品图片库中搜 ...
- Dubbo扩展点应用之三异步调用
Dubbo不只提供了堵塞式的同步调用,同时提供了异步调用的方式.这种方式主要应用于提供者接口响应耗时明显,消费者端可以利用调用接口的时间去做一些其他的接口调用,利用Future模式来异步等待和获取结果 ...
- 2020年的第一天-我的IDEA出现This license ... has been cancelled
IDEA激活在1月3日的早上,激活码被取消了.提示:This license ... has been cancelled. 经过查询.解决方法教程无非是. ¥%--&*(激活码... 210 ...
- mysql is not null 执行效率低
a表字段类型为int b表字段类型为varchar a left join b时如果查询条件是is not null,效率很快,is null 效率很低 后来两者改为同类型 int,效率很高
- python浅拷贝与深拷贝浅析
首先我们要明确,python中大多数都是浅拷贝,我们先说原因: 1.时间花费更少 2.内存更小 3.效率更高,浅拷贝只拷贝顶层数据,一般情况下比深拷贝效率高. 容器(如列表)切片是浅拷贝
- mplus数据分析:增长模型潜增长模型与增长混合模型再解释
混合模型,增长混合模型这些问题咨询的同学还是比较多的,今天再次尝试写写它们的区别,希望对大家进一步理解两种做轨迹的方法有帮助. 首先,无论是LCGA还是GMM,它们都是潜增长模型的框框里面的东西: L ...
- 翻译 | 解读首部 Kubernetes 纪录片
引言 Honeypot.io 自诩为欧洲最大的技术人才招聘平台,同时提供开发者视频网站,又被称其为 "开发者的 Netflix".2022 年 1 月,该公司与 Red Hat.G ...
- 测试平台系列(91) 编写oss管理页面
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持. 欢迎关注我的公众号米洛的测开日记,获取最新文章教程! 回顾 上一节我们编写好了oss相关 ...
- Solon 1.6.30 发布,更现代感的应用开发框架
相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...
- 面试官:Redis中有序集合的内部实现方式是什么?
面试官:Redis中基本的数据类型有哪些? 我:Redis的基本数据类型有:字符串(string).哈希(hash).列表(list).集合(set).有序集合(zset). 面试官:有序集合的内部实 ...