1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 1.undo log: 分 insert/update, update 又分 update/delete; 但无论啥类型, 目的都是辅助事务回滚, 其中 insert 比较简单, 当回滚时根据记录下的主键(联合主键)通过索引找到对应行, 删除即可. 当回滚时 update 是根据记录的主键找到记录后, 再根据记录下的修改过的列数据, 反向修改回去. 当回滚时 delete 是根据记录的整行数据, 然后 insert 回去. 2.但一个事务往往不止一条 SQL, 因此也不止一个 undo log, 每增加一条 SQL, undo log 也随之增加, 这些 undo log 会组成一个链条. 2.若为单个事务, 当回滚时, 情况比较简单, 即只需从链条尾部, 反向遍历, 往前回滚每个 undo log 就行了. 3.若为多个事务, 与单个事务类似, 只是还需要注意链条的维护(即维持链条的连通性)
1.原理是开启事务会创建一个 ReadView, 其作用是判断 undo log 链条中哪些数据是可读的. 2.先说 ReadView, 其存有当前事务 id, 事务启动时那会未提交的事务 id 列表, 所有未提交事务中最小的事务, 下一个事务id; 这里面未提交的事务是重点. 3.RR: 可重复读, 事务一开启则创建一个 ReadView, 直到事务结束; 接着倒着遍历链条, 直到 undo log 是比自己小且不在未提交事务中的事务记录时停下, 仅获取此时的数据, 由于事务开启过程中, ReadView 不改变, 因此整个事务过程中的读取总是一致的. 4.RC: 读已提交, 和 RR 略有不同, 不同之处在于其每次 select 都会重新获取 ReadView, 这使得若有事务提交后, 再 select 数据, 则生成的 ReadView 数据会发生变化(即未提交事务 id 列表中少了刚刚提交的事务). 因此同样的逻辑进行判断, RC 能读取到已提交的事务的改动.
|