博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Fescar - RM undoLog的介绍
阅读量:5873 次
发布时间:2019-06-19

本文共 3535 字,大约阅读时间需要 11 分钟。

开篇

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

undoLog源码介绍

public class TableRecords {    // 表元数据记录    private TableMeta tableMeta;    // 表名    private String tableName;    // 查询获得的行记录    private List
rows = new ArrayList
();}public class Row { // 表的行记录其实表中列字段的集合,Field是column字段。 private List
fields = new ArrayList
();}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
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
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
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对象。

转载地址:http://uhhnx.baihongyu.com/

你可能感兴趣的文章
Web项目启动加载数据至内存--SpringApplicationListener实现
查看>>
Acey.ExcelX4.2版本发布
查看>>
修改支付宝账号的授权方式
查看>>
SET ROWCOUNT
查看>>
NOIP2015DAY2T2子串
查看>>
PHP 程序员的技术成长规划
查看>>
美国插画家Mike Bear作品欣赏
查看>>
zookeeper源码 — 一、单机启动
查看>>
fiddler之请求过滤(Filters)
查看>>
Could not read from remote repository
查看>>
关于“指针数组”和”数组指针“
查看>>
初学者一些常用的SQL语句(二)
查看>>
自我成长
查看>>
论文阅读笔记五十三:Libra R-CNN: Towards Balanced Learning for Object Detection(CVPR2019)
查看>>
ASP.Net Web 服务 – 如何使用会话状态
查看>>
Jetty的JNDI数据源
查看>>
angularjs modal模态框----创建可拖动的指令
查看>>
oracle 视图权限 oracle 创建视图权限不足( ORA-01031: 权限不足)
查看>>
Uva 11218 - KTV
查看>>
队列的链式存储结构
查看>>