MVCC多版本并发控制

ReadView与 MVCC操作流程

MVCC :多版本并发控制
MVCC 的实现依赖于:隐藏字段、Undo Log、Read View

ReadView内容

在这里插入图片描述

ReadView的规则

在这里插入图片描述

MVCC整体操作流程

当查询一条记录的时候,系统如何通过MVCC找到它

  1. 首先获取版本链第一条 trx_id,也就是事务 ID
  2. 获取 ReadView;
  3. 将 trx_id 与 ReadView 中的 trx_id进行比较;
  4. 不符合,换下一条 trx_id
  5. 最后返回符合规则的数据

READ COMMITTED 隔离级别下

READ COMMITTED :每次读取数据前都生成一个ReadView!!!!!!
现在有两个 事务id 分别为 10 20 的事务在执行:

# Transaction 10
BEGIN;
UPDATE student SET name="李四" WHERE id=1;
UPDATE student SET name="王五" WHERE id=1;
# Transaction 20
BEGIN;
# 更新了一些别的表的记录
...

此时进行查询:

# 使用READ COMMITTED隔离级别的事务
BEGIN;
# SELECT1:Transaction 10、20未提交
SELECT * FROM student WHERE id = 1; # 得到的列name的值为'张三'

生成 ReadView视图为:

活跃事务id集合:
trx_ids=[10,20]
此时 up_limit_id :10,low_limit_id:21

表student 中id 为 1的记录得到的版本链表如下所示:
在这里插入图片描述
1、 trx_id=10,在 trx_ids 中,不符合,换下一条
2.、trx_id=10,在 trx_ids 中,不符合,换下一条
3.、trx_id=8, 8<up_limit_id,事务已提交,故:

 SELECT * FROM student WHERE id = 1; # 得到的列name的值为'张三'

REPEATABLE READ隔离级别下

REPEATABLE READ: 只在 第一次进行普通SELECT操作前生成一个ReadView!!!

系统里有两个 事务id 分别为 1020 的事务在执行:

# Transaction 10
BEGIN;
UPDATE student SET name="李四" WHERE id=1;
UPDATE student SET name="王五" WHERE id=1;
# Transaction 20
BEGIN;
# 更新了一些别的表的记录
...

此时进行查询:

# 使用REPEATABLE READ隔离级别的事务
BEGIN;
# SELECT1:Transaction 10、20未提交
SELECT * FROM student WHERE id = 1; # 得到的列name的值为'张三'

生成 ReadView视图为:

活跃事务id集合:
trx_ids=[10,20]
此时 up_limit_id :10,low_limit_id:21

表student 中id 为 1的记录得到的版本链表如下所示:
在这里插入图片描述
1、 trx_id=10,在 trx_ids 中,不符合,换下一条
2.、trx_id=10,在 trx_ids 中,不符合,换下一条
3.、trx_id=8, 8<up_limit_id,事务已提交,故:

 SELECT * FROM student WHERE id = 1; # 得到的列name的值为'张三'

事务id 为 10 的事务提交一下,就像这样:

# Transaction 10
BEGIN;
UPDATE student SET name="李四" WHERE id=1;
UPDATE student SET name="王五" WHERE id=1;
COMMIT;

然后再到事务id 为 20的事务中更新一下表 student 中 id 为 1 的记录:

# Transaction 20
BEGIN;
# 更新了一些别的表的记录
...
UPDATE student SET name="钱七" WHERE id=1;
UPDATE student SET name="宋八" WHERE id=1;

此时进行查询:

# 使用REPEATABLE READ隔离级别的事务
BEGIN;

# SELECT2:Transaction 10提交,Transaction 20未提交
SELECT * FROM student WHERE id = 1; # 得到的列name的值仍为'张三'

还是第一次select时生成的ReadView视图:

活跃事务id集合:
trx_ids=[10,20]
此时 up_limit_id :10,low_limit_id:21

表student 中id 为 1的记录得到的版本链表如下所示:
在这里插入图片描述
1、 trx_id=20,在 trx_ids 中,不符合,换下一条
2、 trx_id=20,在 trx_ids 中,不符合,换下一条
3.、trx_id=10,在 trx_ids 中,不符合,换下一条
4、trx_id=10,在 trx_ids 中,不符合,换下一条
5.、trx_id=8, 8<up_limit_id,事务已提交,故:

 SELECT * FROM student WHERE id = 1; # 得到的列name的值为'张三'

解决幻读

根据 ReadView的规则分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值