H2 Database 事务 Rollback 实现原理

H2 Database 事务 Rollback 流程实现原理

使用

Connection conn = getConnection();
// 开启事务
conn.setAutoCommit(false);
// 执行 SQL
executeWithLog(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 信息。

获取 transaction id 和 当前 undo log id.
从当前 undo log id 一直遍历到 0(事务刚开启时 undoLogId=0),回滚当前事务的所有操作.
    根据 undo log key 定位到 undo log btree 上的指定位置,获取存储的 record
        record 包含当前 undo log 操作的 mvMap(比如 Primary key) 的 mapId, key(比如主键 id), oldValue
    再根据 record 打开 primary key mvMap,定位到 row key, 然后决定从 mvMap 上移除当前值
    再移除 undo log mvMap 上的当前 undo log key 对应的值

代码流程

org.h2.jdbc.JdbcStatement#executeInternal
    org.h2.jdbc.JdbcConnection#prepareCommand
    解析 rollback 语句
    org.h2.command.Command#executeUpdate
        org.h2.engine.SessionLocal#setSavepoint 
        设置savepoint,返回新的logId
        org.h2.command.dml.TransactionCommand#update
            org.h2.engine.SessionLocal#rollback
                org.h2.engine.SessionLocal#hasTransaction 
                判断在事务中
                org.h2.engine.SessionLocal#rollbackTo 
                执行回滚
                    org.h2.mvstore.tx.Transaction#rollback 
                    回滚
                        org.h2.mvstore.tx.Transaction#setStatus 
                        1.尝试设置事务状态为 ROLLED_BACK,并获取之前的事务状态
                            获取事务当前的 state & logId
                            org.h2.mvstore.tx.Transaction#getLogId 
                            获取当前 undo log id
                            org.h2.mvstore.tx.Transaction#getStatus 
                            获取事务当前状态
                            2.判断当前状态允许变更为目标状态,然后变更为目标状态
                            org.h2.mvstore.tx.Transaction#composeState 新状态(transaction status + undo log id)
                            3.原子变更 statusAndLogId
                        获取当前 status 和 logId
                        org.h2.mvstore.tx.TransactionStore#rollbackTo 
                        回滚
                            org.h2.mvstore.tx.RollbackDecisionMaker#init0 
                            创建 rollback decision maker
                            3.遍历从 maxLogId 到 toLogId,依次进行回滚操作
                            org.h2.mvstore.tx.TransactionStore#getOperationId 
                            3.1.计算 undo log key (transaction id + log id)
                            org.h2.mvstore.MVMap#operate 
                            3.2.根据 undo log key 操作 undo log mvMap, 执行回滚操作
                                org.h2.mvstore.MVMap#flushAndGetRoot 
                                获取 undo log mvMap 根节点
                                org.h2.mvstore.CursorPos#traverseDown 
                                找到 undoLog 位置
                                org.h2.mvstore.MVMap.DecisionMaker#decide 
                                内部会先回滚该 undoLog 对应的 mvMap上 对应 row
                                    org.h2.mvstore.tx.RollbackDecisionMaker#decide
                                        1.获取 undo log record 
                                        里当前存储的旧值
                                        org.h2.mvstore.tx.TransactionStore#openMap 
                                        3.获取数据行对应 mvMap(比如 primary key mvMap)
                                        org.h2.mvstore.MVMap#operate 
                                        回滚数据行
                                            org.h2.mvstore.MVMap#flushAndGetRoot 
                                            获取表根节点
                                            org.h2.mvstore.CursorPos#traverseDown 
                                            找到数据行
                                            org.h2.mvstore.Page.Leaf#remove 
                                            移除数据行
                                org.h2.mvstore.Page.Leaf#remove 
                                移除 undo log 叶子节点
                        org.h2.mvstore.tx.TransactionStore#endTransaction
                                org.h2.mvstore.tx.Transaction#setStatus
                                修改状态
                org.h2.engine.SessionLocal#endTransaction
                    org.h2.engine.SessionLocal#unlockAll
                    释放锁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlyingZCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值