首页 > 技术文章 > MySQL事物隔离级别的解决方案MVVC

ssskkk 2020-08-22 23:27 原文

数据隔离级别解决方案

第一种:在读取数据前,对其加锁,阻止其他事物对数据进行修改——Lock Based Concurrency Control(LBCC)

第二种:生成一个数据请求时间点的一致性数据快照(Snapshot),并用这个快照来提供一定级别的一致性读取

相对于第二种:第一种在读写的时候 能够不用竞争锁,从而提高性能

Multi Version Concurrency Control(MVVC) 主要包括

undo log:每次update生成的日志

版本链:由回滚指针和undolog连接起来的

快照:也就是read-view,让你知道你在版本链里拿哪一条记录。

当执行查询SQL时,会生成一致性视图 read-view

1. read-view对象包括

  1)查询时所有未提交事物id数组(还没有commit),也叫活跃事物ids(如果是可重复读 这个ids在某个事物中不会变)

  2)生成这个read-view的事物id trx_id

如[100,200],300

2.undo log

每次Update操作都会生成一个undolog日志,Mysql底层会给每张表加两个字段 事物id(trx_id)和回滚指针(roll_pointer)

MVVC比对规则(read-view和版本链比对规则)

read-view视图会和undo日志版本链进行对比,判断版本链中哪个版本可用,版本链比对规则如下:

如果要读取的事物id的trx_id

  1)小于min_Id 数据可见(说明这个trx_id是已经commit的了)

  2)大于max_Id 数据不可见(读取数据的时候 只能读版本链里的数据) 如果是不可重复读,会生成新的read-view,则这个trx_id 不会大于max_id 则可见。

  3)在min_Id和max_Id之间:若rowtx-id在数组(ids)中表示这个版本是由还没提交事物生成的,不可见(因为ids还没有commit)

                       若rowtx-id不在数组中,表示这个版本是由已经提交的事物生成,可见

根据这个判断条件就可以在版本链里面读取我们应该读取的事物

不可重复读(读已提交):每次select时都会按最新的一次生成read-view

可重复读:沿用事物中第一条select语句的read-view(其中read-view是session级别的,所有表都会沿用)

如果数据不可见,会根据版本链的roll_pointer指针找到上一条数据,直到找到可见的数据

不同的session拿到的结果集不一样,并不是因为数据被赋值的多份,而是不同session的read-view不同

 

推荐阅读