MySql中事务隔离级别的解决方案MVCC

对于MySql四种事务隔离级别,为了保证其数据一致性和高并发场景下的性能,于是使用MVCC。

MVCC是生成一个数据请求时间点的一致性数据快照,并用这个快照来提供一定级别的一致性读取。
也就是相当于一定时间内的所有查询都查这个数据块照里的内容,这样保证了读一致性,解决了不可重复读。

原理:在MySql中,Innodb引擎为每条记录都提供了三个隐藏字段,
DB_ROW_ID – 行标识,在没有索引的时候为默认索引,没有索引的时候操作会锁表,因为锁住了所有的DB_ROW_ID
DB_TRX_ID – 插入或更新行的最后一个事务的事务ID,自动递增。也就相当于是版本号
DB_ROLL_PTR – 回滚指针 (删除版本号)

DB_TRX_ID:每一行记录的这个值,就是代表最后一次更新(插入或者更新)该条记录的事务ID。

每个事务查询,只能查找到创建时间小于等于当前事务ID的(已提交的)数据,和删除时间大于当前事务ID的行(或未删除)

前半句好理解,就是查询事务只能查到在这个事务之前的数据,在这个事务之后,其他事务进行的操作,查不到。

后半句可能难以理解,删除时间大于当前事务ID的行怎么还会被查到呢?不是已经删除了吗?
实际上看MVCC的描述,它是一个数据快照,也就是说虽然这条数据删除了(如果再次查询表会发现表里已经没有这条数据了),但是在数据快照里,它还未删除
只是更新了隐藏字段 DB_ROLL_PTR 的值(变为了删除事务的ID)。

还有的人疑惑一个点,可以在这里讨论一下:
比如事务1开启事务,事务2开启事务查询,此时没有数据,事务1版本号小于事务2,事务1新增数据,提交,那么事务2能查到新的数据吗?
按规则来说是能查到,但是这样就产生幻读的现象。而Innodb在RR(可重复读)中是解决了幻读的。

解答:应该是需要借助,readview undo log 间隙锁 日后有机会再补充吧。

你可能感兴趣的:(随便写着玩)