H2 Database 事务隔离性实现原理
H2 Database 事务隔离性实现原理使用测试 cases:
12345678910111213隔离级别 RC A 开启事务 B 开启事务 B 插入数据并提交 A 可以读取到隔离级别 RR A 开启事务 B 开启事务 A 查询 B 插入数据并提交 A 读取不到 A 自己插入数据 A 可以读取到自己插入的数据
功能H2 支持的事务隔离级别,定义在 IsolationLevel 里。包括 READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SNAPSHOT, SERIALIZABLE。其中 REPEATABLE_READ 不允许出现 脏读 和 不可重复读,但是允许出现幻读。SNAPSHOT 不允许出现 脏读 和 不可重复读 和 幻读。
12345678910111213141516171819202122232425262728293031323334/** * Level of isolation. */public enum IsolationLevel { ...
H2 Database Select 语句执行流程
使用1234// CREATE TABLE IF NOT EXISTS test(id INT primary key, name VARCHAR(255))// insert into test(id, name) values(1, 'name1'), (2, 'name2'), (3, 'name3'), (4, 'name4');String sql = "SELECT * FROM test where id > 1 and name='name3'";ResultSet rs = stmt.executeQuery(sql);
查询 case:
1234主键查询覆盖索引查询索引查询+回表多表关联查询
功能模块类总体流程12345678910111213Select 语句 SQL 解析Select 语句 SQL 查询优化 计算执行计划的成本 创建查询优化器 优化查询计划 计算最佳查询计划 测试并更新最优查询计划 ...
H2 Database 事务 Rollback 流程实现原理
H2 Database 事务 Rollback 流程实现原理使用1234567Connection conn = getConnection();// 开启事务conn.setAutoCommit(false);// 执行 SQLexecuteWithLog(conn, "insert into Test(id, name) values(1, 'name1'), (2, 'name2')");// 回滚事务conn.rollback();
功能模块类总体流程当执行事务回滚时,会获取当前事务所有的 undoLogId,然后从后向前遍历每一个 undoLogId。对于每一个 undoLogId,先遍历 undoLog btree 找到存储的 Record。Record 信息里包含了当前 undoLogId 操作的数据行信息。然后根据 Record 信息找到对应记录的 primary key btree,根据主键 id 找到对应行记录进行回滚操作。当记录回滚完之后,再回滚 undoLog btree 上的 undoLog 信息。 ...
H2 Database MVStore Commit 流程
H2 Database MVStore Commit 流程作用BackgroundWriterThread 按照固定频率,将内存里修改的尚未保存的 Page 信息持久化到存储。
流程启动阶段创建后台线程org.h2.mvstore.MVStore#setAutoCommitDelay1.创建 BackgroundWriterThread 后台线程2.创建序列化线程 serializationExecutor3.创建持久化线程 bufferSaveExecutor设置自动提交更改的最大延迟(单位毫秒)。 默认值为 1000,这意味着所有更改最多在一秒后提交。 要禁用自动提交,需要将值设置为 0。在这种情况下,仅在显式调用 commit 时才会提交更改。
BackgroundWriterThread 线程逻辑定时任务周期性执行,比对内存里的 MVMap 版本号和上一次持久化的版本号是否有变更,有则收集变更的根节点,进行后续处理.
1234567891011121314151617181920212223242526org.h2.mvstore.FileStore.BackgroundW ...
H2 Database MvMap 插入数据流程
H2 Database MvMap 插入数据流程使用12345678// 1.根据数据库文件名称打开 mvStoreMVStore s = MVStore.open(fileName);// 2.指定名称创建 mvMapMVMap<Integer, String> map = s.openMap("data");// 3.将数据插入到 mvMap 上for (int i = 0; i < 400; i++) { map.put(i, "Hello-" + i);}
作用插入 key, value 到 mvMap 上的指定位置。
流程主要逻辑在 MVMap#operate 里。
123456789101112131415161718192021222324252627282930311.获取 mvMap 根节点引用,获取对应的根节点 root page2.从根节点开始二分遍历,根据 key 遍历 btree,找到 key 所在的位置 pos CursorPos.traverseDown(rootP ...
H2 Database 事务 Commit 流程实现原理
H2 Database 事务 Commit 流程实现原理使用测试 Demo:
123begin;insert into test values(1);commit;
功能模块类总体流程1234567891011121314解析 commit 语句执行 commit 语句 设置事务状态为已提交 根据 undoLogId 判断事务是否有更改操作,有更改继续提交 CAS 设置当前事务状态为已提交到 committingTransactions 遍历 undoLog mvMap 追加标记 undoLog 已提交到 undoLog mvMap 上 获取当前 undoLog 操作涉及的 mvMap id 遍历到对应 Page 的对应 index 将 VersionedValueUncommitted 类型更新成 DefaultRow 类型事务清理操作 清理 undoLog mvMap(更新 root 节点为 empty) 清理事务状态 释放 table 锁
代码流程12345678 ...
H2 Database SQL 插入流程
H2Database SQL 插入流程插入数据时会先进行 SQL 解析,然后找到插入表对应的 Primary Index 对应的 BTree,然后根据二分法定位到插入的叶子节点,将 key(主键) 和 value(Row) 插入到指定的叶子节点.
12345678910111213141516171819202122232425262728293031解析 SQLsession 加锁创建 savepoint 获取or创建事务设置 savepoint执行 insert 插入操作 表权限校验 创建模板行 从 insert values 表达式获取值,设置到当前 row 里 将 value 转换成指定类型 table 加 share 锁 添加行数据 添加数据行到主键索引 获取根节点 二分查找定位到 btree 插入位置 记录事务 undo log 到 buffer 写入 undo log 时,会将 undo log 的 btree 加锁,当数 ...
H2 Database MVStore 初始化
H2 Database MVStore 初始化作用MVStore(multi-version store):H2 的默认存储子系统,支持多版本,持久化的、日志结构 的 键值存储。
功能123456789101112Maps 每个 store 包含多个 mvMaps,可以通过 java.util.Map 接口访问Versions 支持多版本Transactions 支持事务(并发事务&两阶段提交)Concurrent Operations and Caching 支持并发读写Log Structured Storage 日志结构化存储支持文件存储和内存操作支持可插拔
文件存储格式12345# 文件存储格式[ file header 1 ] [ file header 2 ] [ chunk ] [ chunk ] ... [ chunk ]# chunk 存储格式[ header ] [ page ] [ page ] ... [ page ] [ footer ]
12345结构 File Header 文件头 Chunk Form ...
H2 Database IDEA 环境搭建
H2 Database IDEA 源码 DEBUG 环境搭建基于最新的 version-2.3.230 拉取分支。
123git remote add h2 https://github.com/h2database/h2database.git git fetch h2git checkout -b version-2.3.230 version-2.3.230
使用12345# 启动java -jar h2*.jar# H2 shell 方式使用java -cp h2-*.jar org.h2.tools.Shell
h2 shell启动类 org.h2.tools.Shell
12# 配置启动参数-url "jdbc:h2:~/test" -user "sa" -password ""
测试 casecreate table + insert
1234567891011121314151617181920212223242526272829303132333435363738394041Welcome to H2 ...
Apache Omid Client 组件实现原理
Apache Omid Client 组件实现原理作用通过 TransactionManager 开启/提交/回滚事务,提供事务内快照隔离级别的读写操作。
使用123456789101112131415// 1.创建 transaction managerTransactionManager tm = HBaseTransactionManager.newInstance();// 2.通过 transactin manger 开启事务Transaction tx0 = tm.begin();// 3.事务内插入数据byte[] rowId = rowIdGenerator.getRowId();Put initialPut = new Put(rowId);initialPut.addColumn(family, qualifier, initialData);txTable.put(tx0, initialPut);// 4.事务内读取数据Get tx2Get = new Get(rowId);tx2Get.addColumn(family, qualifier ...