zoukankan      html  css  js  c++  java
  • seata 分布式事务 -- AT模式

    模块组成:


    1)TM:事务发起者。定义事务的边界,负责告知 TC,分布式事务的开始,提交,回滚。

    2)RM:资源管理者。管理每个分支事务的资源,每一个 RM 都会作为一个分支事务注册在 TC。

    3)TC :事务协调者。负责我们的事务ID的生成,事务注册、提交、回滚等。


    AT模式的前提是基于支持本地 ACID 事务的关系型数据库和Java应用基于JDBC访问数据库。

    AT模式是二阶段提交协议的演变:

    一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
    
    二阶段:commit异步化快速完成;rollback通过一阶段的回滚日志进行反向补偿。


    读写隔离:

    写隔离保证是通过全局锁来保证的,一阶段事务提交前必须要拿到全局锁,否则不能提交本地事务,

    获取全局锁过程中不能无限等待,超时后放弃,并回滚本地事务,释放本地锁(避免产生死锁)。

     


    举例:

    假设 tx1 先拿到本地锁,执行流程:


    结果:
    tx1 此时只能等 (等 tx2 获取全局锁超时,回滚 tx2 第二步执行的Sql,释放掉本地锁)
    然后再获取本地锁回滚 第一步 执行的Sql.

     

     


    工作机制:

    一阶段:

    解析 SQL:得到 SQL 的类型(UPDATE),表(product),条件(where name = 'TXC')等相关的信息。
    查询前镜像:根据解析得到的条件信息,生成查询语句,定位数据。
    执行业务 SQL:执行业务更新SQL。
    查询后镜像:根据前镜像的结果,通过 主键 定位数据。
    插入回滚日志:把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 UNDO_LOG 表中。
    提交前,向 TC 注册分支:申请 product 表中,主键值等于 1 的记录的 全局锁 。
    本地事务提交:业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交。
    将本地事务提交的结果上报给 TC。
    一阶段在分支事务提交前向TC注册分支,进行一次通信。

    二阶段-回滚:

    收到 TC 的分支回滚请求,开启一个本地事务,执行如下操作。
    通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。
    数据校验:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理,详细的说明在另外的文档中介绍。
    根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句。
    提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。

    二阶段-提交:

    收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。
    异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。


    简单理解:

    一个典型的事务过程:

    1. TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID。

    2. XID 在微服务调用链路的上下文中传播。

    3. RM 向 TC 注册分支事务,将其纳入 XID 对应全局事务的管辖。

    4. TM 向 TC 发起针对 XID 的全局提交或回滚决议。

    5. TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。

     

    AT 模 式 需 要 用 到 的 数 据 库 表 :

    创建 undo_log 表, sql语句 :

    DROP TABLE IF EXISTS `undo_log`;
    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,
    `ext` varchar(100) DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8;

     

  • 相关阅读:
    Python基础
    熟悉常见的Linux操作
    大数据概述
    实验报告(3)-语法分析
    LL(1)文法
    简化版C语言文法
    实验报告(1)-词法分析
    中文词频统计
    综合练习:英文词频统计
    字符串练习
  • 原文地址:https://www.cnblogs.com/lifan12589/p/14780927.html
Copyright © 2011-2022 走看看