一,什么是事务(本地事务)?

指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。

简单的说,事务就是并发控制的单位,是用户定义的一个操作序列。

     而一个逻辑工作单元要成为事务,就必须满足ACID属性。
     A:原子性(Atomicity)
     事务中的操作要么都不做,要么就全做。
    C:一致性(Consistency)
    事务执行的结果必须是从数据库从一个一致性状态转换到另一个一致性状态。
   I:隔离性(Isolation) 
   一个事务的执行不能被其他事务干扰
   D:持久性(Durability)
   一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。

注:如果对事务不是很懂可以参考这篇文章:什么是事务?事务的四个特性以及事务的隔离级别 - Kevin.ZhangCG - 博客园 (cnblogs.com)  

二, 分布式事务

​ 随着互联网的快速发展,软件系统由原来的单体应用转变为分布式应用,下图描述了单体应用向微服务的演变:

​ 分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务。

三,分布式事务产生的情景

  1. 跨JVM进程产生分布式事务
    典型的场景就是微服务架构:微服务之间通过远程调用完成事务操作。比如:订单微服务和库存微服务,下单的同时订单微服务请求库存微服务减少库存。

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

  1. 多服务访问同一个数据库实例
    订单微服务和库存微服务即使访问同一个数据库也会产生分布式事务,原因就是跨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 支持两阶段提交协议,如下图:

  1. 准备阶段(Prepare phase):事务管理器给每个参与者发送 Prepare 消息,每个数据库参与者在本地执行事务,并写本地的 Undo/Redo 日志,此时事务没有提交。(Undo 日志是记录修改前的数据,用于数据库回滚,Redo 日志是记录修改后的数据,用于提交事务后写入数据文件)
  2. 提交阶段(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 详解(小白都能看懂)的更多相关文章

  1. 搭建分布式事务组件 seata 的Server 端和Client 端详解(小白都能看懂)

    一,server 端的存储模式为:Server 端 存 储 模 式 (store-mode) 支 持 三 种 : file: ( 默 认 ) 单 机 模 式 , 全 局 事 务 会 话 信 息 内 存 ...

  2. Spring Cloud Alibaba 初体验(六) Seata 及结合 MyBatis 与 MyBatis-Plus 的使用

    一.下载与运行 本文使用 Seata 1.1.0:https://github.com/seata/seata/releases Windows 环境下双击 bin/seata-server.bat ...

  3. Spring Cloud内置的Zuul过滤器详解

    Spring Cloud默认为Zuul编写并启用了一些过滤器,这些过滤器有什么作用呢?我们不妨按照@EnableZuulServer.@EnableZuulProxy两个注解进行展开,相信大家对这两个 ...

  4. spring的annotation-driven配置事务管理器详解

    http://blog.sina.com.cn/s/blog_8f61307b0100ynfb.html ——————————————————————————————————————————————— ...

  5. 小白都能看懂的Spring源码揭秘之IOC容器源码分析

    目录 前言 IOC 只是一个 Map 集合 IOC 三大核心接口 IOC 初始化三大步骤 定位 加载 注册 总结 前言 在 Spring 框架中,大家耳熟能详的无非就是 IOC,DI,Spring M ...

  6. 小白都能看懂的 Spring 源码揭秘之Spring MVC

    目录 前言 Spring MVC 请求流程 Spring MVC 两大阶段 初始化 HttpServletBean#init() FrameworkServlet#initServletBean Fr ...

  7. 小白都能看懂的 Spring 源码揭秘之依赖注入(DI)源码分析

    目录 前言 依赖注入的入口方法 依赖注入流程分析 AbstractBeanFactory#getBean AbstractBeanFactory#doGetBean AbstractAutowireC ...

  8. Spring Cloud Alibaba 新一代微服务解决方案

    本篇是「跟我学 Spring Cloud Alibaba」系列的第一篇, 每期文章会在公众号「架构进化论」进行首发更新,欢迎关注. 1.Spring Cloud Alibaba 是什么 Spring ...

  9. Spring Cloud Alibaba 教程 | 前世今生

    Spring Cloud Alibaba是什么 先来看一下官方是怎么定义Spring Cloud Alibaba的: Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案.此 ...

随机推荐

  1. 最好的Java开发工具---IDEA

    IntelliJ IDEA工具的使用 1. 常见的Java集成开发工具 Eclipse IBM团队研发的一个开源的非常好用的集成开发环境.寓意:吞并Sun公司.不过Sun最终被Oracle公司收购了. ...

  2. js reduce累加器

    ​ reduce 是es6 新增的数组操作方法 意为累加器 使用方法如下 [1,1,1,1].reduce((total,currentValue,index)=>{ },initialValu ...

  3. Solution -「JOISC 2021」古老的机器

    \(\mathcal{Description}\)   Link.   这是一道通信题.   对于长度为一个 \(n\),仅包含字符 X, Y, Z 的字符串 \(s\),将其中 \(n\) 个字符按 ...

  4. Solution -「CF 1370F2」The Hidden Pair (Hard Version)

    \(\mathcal{Description}\)   Link (hard) & Link (easy).   这是一道交互题.   给定一棵 \(n\) 个结点的树,其中有两个是特殊结点. ...

  5. 从浅入深掌握并发执行框架Executor

    引言 任务的执行 大多数并发应用程序都是围绕"任务执行(Task  Execution)"来构造的:任务通常是一些抽象的且离散的工作单元. 任务通常是一些抽象的且离散的工作单元.通 ...

  6. figlet 一个在linux生成字符串图案的玩具

    figlet官网 figlet官方字体库 figlet字体样例 安装方法 centos/redhat/fedora 发行版 yum install -y figlet debian/ubuntu 发行 ...

  7. 查看树莓派系统相关信息的shell代码

    一.系统信息 1.显示系统名.系统版本和cpu架构等 在命令行中输入下面的指令 uname -a 2.系统位数 在命令行中输入下面的指令 getconf LONG_BIT 如图,显示多少就是多少位 3 ...

  8. 微信公众平台网页授权登陆access_token误区

    公众平台里显示 每日获取access_token上线2000次,此access_token并非网页授权登陆的access_token大家不要混淆 1,网页授权登陆的access_token是没有上线的 ...

  9. 软件性能测试分析与调优实践之路-Java应用程序的性能分析与调优-手稿节选

    Java编程语言自从诞生起,就成为了一门非常流行的编程语言,覆盖了互联网.安卓应用.后端应用.大数据等很多技术领域,因此Java应用程序的性能分析和调优也是一门非常重要的课题.Java应用程序的性能直 ...

  10. 自助式BI工具怎么选?这款用过都说好!

    随着大数据时代的到来,很多公司的业务数据量不断增长,公司必须集中精力管理数据,并在BI工具的帮助下进行数据分析,以便从过去的数据中获得洞察力,预测未来的发展.近年来,随着企业对数据的关注度的增加,企业 ...