本文共 3535 字,大约阅读时间需要 11 分钟。
这篇文章的目的是介绍Fescar当中回滚日志undoLog的数据结构,为后续RM执行回滚动作rollback打下基础,因为undoLog涉及的数据结构用源码表示起来比较简单通俗易懂,所以直接根据源码进行讲解。
public class TableRecords { // 表元数据记录 private TableMeta tableMeta; // 表名 private String tableName; // 查询获得的行记录 private Listrows = 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;}
说明::
public abstract class BaseTransactionalExecutorimplements 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); }}
说明:
public abstract class BaseTransactionalExecutorimplements 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(); }}
说明:
public class SQLUndoLog { // SQL的类型 private SQLType sqlType; // 表名 private String tableName; // 执行前镜像 private TableRecords beforeImage; // 执行后镜像 private TableRecords afterImage;}public abstract class BaseTransactionalExecutorimplements 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; }}
说明:
个人认为重点在于undoLog的lockKey的生成逻辑以及保存的容器在于connectionProxy对象。
转载地址:http://uhhnx.baihongyu.com/