Fescar - RM undoLog的介绍

简介: 开篇 这篇文章的目的是介绍Fescar当中回滚日志undoLog的数据结构,为后续RM执行回滚动作rollback打下基础,因为undoLog涉及的数据结构用源码表示起来比较简单通俗易懂,所以直接根据源码进行讲解。

开篇

 这篇文章的目的是介绍Fescar当中回滚日志undoLog的数据结构,为后续RM执行回滚动作rollback打下基础,因为undoLog涉及的数据结构用源码表示起来比较简单通俗易懂,所以直接根据源码进行讲解。


undoLog源码介绍

public class TableRecords {
    // 表元数据记录
    private TableMeta tableMeta;
    // 表名
    private String tableName;
    // 查询获得的行记录
    private List<Row> rows = new ArrayList<Row>();
}

public class Row {
    // 表的行记录其实表中列字段的集合,Field是column字段。
    private List<Field> fields = new ArrayList<Field>();
}

public class Field {

    // 列名
    public String name;

    private KeyType keyType = KeyType.NULL;

    // 列的字段类型。
    public int type;

    // 列的值
    public Object value;
}

说明:

  • 介绍UndoLog对象之前必须先了解构建UndoLog的原始记录beforeImage和afterImage对象。
  • TableRecords beforeImage = beforeImage()中TableRecords保存SQL执行前后数据镜像。
  • TableRecords顾名思义就是表当中的数据记录,保存从数据表中查询得到的行记录。
  • TableRecords中的List是行记录的集合。
  • Row中的List是单行当中的列字段column。
  • Field是描述单列的数据结构,包含列的字段名,字段类型,字段值等。


public abstract class BaseTransactionalExecutor<T, S extends Statement> implements Executor {

    protected void prepareUndoLog(TableRecords beforeImage, TableRecords afterImage) throws SQLException {
        if (beforeImage.getRows().size() == 0 && afterImage.getRows().size() == 0) {
            return;
        }

        ConnectionProxy connectionProxy = statementProxy.getConnectionProxy();

        // 生成TC的全局锁对象lockKeys  
        TableRecords lockKeyRecords = sqlRecognizer.getSQLType() == SQLType.DELETE ? beforeImage : afterImage;

        // 根据SQL类型区分生成锁字段的原始素材
        String lockKeys = buildLockKey(lockKeyRecords);

        // 将锁字段保存到connectionProxy的维度
        connectionProxy.appendLockKey(lockKeys);

        // 准备SQLUndoLog
        SQLUndoLog sqlUndoLog = buildUndoItem(beforeImage, afterImage);

       // 将回滚日志保存到connectionProxy的维度
        connectionProxy.appendUndoLog(sqlUndoLog);
    }
}

说明:

  • 根据SQL类型区分生成锁字段的原始素材beforeImage或afterImage。
  • 将锁字段保存到connectionProxy的维度
  • 准备SQLUndoLog,通过beforeImage或afterImage。
  • 将回滚日志sqlUndoLog保存到connectionProxy的维度


public abstract class BaseTransactionalExecutor<T, S extends Statement> implements Executor {

    protected String buildLockKey(TableRecords rowsIncludingPK) {
        if (rowsIncludingPK.size() == 0) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(rowsIncludingPK.getTableMeta().getTableName());
        sb.append(":");

        boolean flag = false;
        for (Field field : rowsIncludingPK.pkRows()) {
            if (flag) {
                sb.append(",");
            } else {
                flag = true;
            }
            sb.append(field.getValue());
        }
        return sb.toString();
    }
}

说明:

  • 锁字段的生成逻辑是表名:primaryKey的列值。
  • 锁字段的生成逻辑是表名加pk的值。
  • 关注外层的for循环,如果变更多条记录即多个row记录,就拼接所有row记录的pk的值。


public class SQLUndoLog {
    // SQL的类型
    private SQLType sqlType;
    // 表名
    private String tableName;
    // 执行前镜像
    private TableRecords beforeImage;
    // 执行后镜像
    private TableRecords afterImage;
}


public abstract class BaseTransactionalExecutor<T, S extends Statement> implements Executor {

    protected SQLUndoLog buildUndoItem(TableRecords beforeImage, TableRecords afterImage) {
        SQLType sqlType = sqlRecognizer.getSQLType();
        String tableName = sqlRecognizer.getTableName();

        SQLUndoLog sqlUndoLog = new SQLUndoLog();
        sqlUndoLog.setSqlType(sqlType);
        sqlUndoLog.setTableName(tableName);
        sqlUndoLog.setBeforeImage(beforeImage);
        sqlUndoLog.setAfterImage(afterImage);

        return sqlUndoLog;
    }
}

说明:

  • SQLUndoLog的数据结构如上所示,包括SQL类型、表名、执行前后镜像。
  • buildUndoItem的构建UndoItem的逻辑就是保存上述提到的基础数据。


重点

 个人认为重点在于undoLog的lockKey的生成逻辑以及保存的容器在于connectionProxy对象。

目录
相关文章
|
前端开发 JavaScript 数据可视化
标准微前端架构在蚂蚁的落地实践
蚂蚁金服前端技术专家有知在 D2 带来以“标准微前端架构在蚂蚁的落地实践”为题的演讲。首先提出了微前端的场景域在蚂蚁落地时常遇到的问题,然后详细介绍了微前端的定义,最后通过实施一个标准的微前端架构,提出面临的技术决策以及需要处理的技术细节,经过在蚂蚁的实践证明,微前端是一个具有优势的方案。
15959 0
标准微前端架构在蚂蚁的落地实践
|
4月前
|
存储 缓存 安全
synchronized 底层全解:从对象头、锁升级到内核实现,击穿并发编程的核心基石
本文深度剖析Java中synchronized的底层原理:从三种使用范式、字节码实现,到对象内存布局、Mark Word状态切换,详解锁升级(偏向→轻量→重量)全流程及JVM优化(锁消除/粗化),并结合JOL实战验证,兼顾理论深度与生产实用性。
549 2
|
7月前
|
PHP 开发工具 Android开发
语音房社交软件开发/php开发/社交同城交友/语音房APP开发与社交功能的融合
本文介绍语音社交应用的两种开发路径:定制开发适合有独特需求的大中型企业,功能灵活但成本高、周期长;基于成熟方案快速搭建则适合初创团队,利用声网、腾讯云等RTC厂商的开源Demo,低成本高效启动。同时探讨如何通过轻互动、用户标签、个人主页、语音动态等功能,将语音房临时互动转化为长期社交关系,并强调合规、性能与MVP冷启动策略的重要性。(238字)
475 3
|
4月前
|
存储 人工智能 Serverless
替换一个节点,ComfyUI 瞬间起飞
FunArt是阿里云函数计算推出的ComfyUI一键托管平台,集成VisionPlaid等高性能DiT推理引擎,支持多卡序列并行、4-bit量化与异步Offload,在保持原生兼容前提下显著加速图像/视频生成,真正实现开箱即用、弹性高可用的AI生成服务。
|
人工智能 自然语言处理 安全
AI战略丨新一代 AI 应用: 穿透场景,释放价值
在深入理解技术特性、准确把握应用场景、科学评估实施条件的基础上,企业才能制定出符合自身实际的战略。
|
11月前
|
缓存 API 网络架构
淘宝item_search_similar - 搜索相似的商品API接口,用python返回数据
淘宝联盟开放平台中,可通过“物料优选接口”(taobao.tbk.dg.optimus.material)实现“搜索相似商品”功能。该接口支持根据商品 ID 获取相似推荐商品,并返回商品信息、价格、优惠等数据,适用于商品推荐、比价等场景。本文提供基于 Python 的实现示例,包含接口调用、数据解析及结果展示。使用时需配置淘宝联盟的 appkey、appsecret 和 adzone_id,并注意接口调用频率限制和使用规范。
|
11月前
|
JSON Unix API
1688查询榜单列表API详解
1688榜单API提供实时热销、新品等商品榜单数据,支持20+品类及40+字段筛选,适用于选品与市场分析。每小时更新,响应迅速。提供Python调用示例,开发者可快速集成。
|
人工智能 算法 架构师
人工智能认证就业:从能力认证到职业跃迁的路径解析
人工智能浪潮席卷全球,AI技术正深刻重构职业生态。生成式人工智能认证(GAI认证)应运而生,作为系统化能力认证体系,它不仅帮助个人锚定技术方向,也为企业提供可靠的人才评估标尺。本文从宏观与个体视角探讨AI认证的价值:宏观上,认证体系是人才市场的“通用语言”,助力伦理合规;个体层面,认证能打破经验壁垒、实现职业跃迁,并通过体系化学习提升安全感。GAI认证以“技术深度+场景广度+伦理高度”设计,成为连接技术变革与职业发展的桥梁,鼓励每个人成为AI时代的“能力架构师”。
|
7月前
|
Java Shell 开发工具
【Git入门】Git常用命令大全:从add到push,一图胜千言
本文深入浅出地讲解Git核心概念与常用命令,涵盖工作区、暂存区、本地仓库和远程仓库三大区域,梳理从配置、克隆、提交到同步的完整流程,并介绍撤销修改、查看历史、.gitignore等实用技巧,助力开发者高效协作。