当前位置:首页 > mysql > 正文内容

mysql中可重复读隔离级别的实现原理

phpmianshi4年前 (2017-04-08)mysql459

原理


MySQL默认的隔离级别是可重复读,即:事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容。 那么MySQL可重复读是如何实现的呢?

使用的的一种叫MVCC的控制方式 ,即Mutil-Version Concurrency Control,多版本并发控制,类似于乐观锁的一种实现方式

实现方式

InnoDB在每行记录后面保存两个隐藏的列来,分别保存了这个行的创建时间和行的删除时间。这里存储的并不是实际的时间值,而是系统版本号,当数据被修改时,版本号加1
在读取事务开始时,系统会给当前读事务一个版本号,事务会读取版本号<=当前版本号的数据
此时如果其他写事务修改了这条数据,那么这条数据的版本号就会加1,从而比当前读事务的版本号高,读事务自然而然的就读不到更新后的数据了


增删改查


假设初始版本号为1:

INSERT

insert into user (id,name) values (1,'Tom');
idnamecreate_versiondelete_version
1Tom1

下面模拟一下文章开头的场景:

SELECT (事务A)

select * from user where id = 1;

此时读到的版本号为1

UPDATE(事务B)

update user set name = 'Jerry' where id = 1;

在更新操作的时候,该事务的版本号在原来的基础上加1,所以版本号为2。
先将要更新的这条数据标记为已删除,并且删除的版本号是当前事务的版本号,然后插入一行新的记录

idnamecreate_versiondelete_version
1Tom12
1Jerry2

SELECT (事务A)

此时事务A再重新读数据:

select * from user where id = 1;

由于事务A一直没提交,所以此时读到的版本号还是为1,所以读到的还是Tom这条数据,也就是可重复读

DELETE

delete from user where id = 1;

在删除操作的时候,该事务的版本号在原来的基础上加1,所以版本号为3
删除时,将当前版本号作为删除版本号

idnamecreate_versiondelete_version
1Jerry23


版权声明:本文由PHP面试资料网发布,如需转载请注明出处。
分享给朋友:

相关文章

mysql中QueryCache优化

原理 MySQL 的 Query Cache 实现原理实际上并不是特别的复杂,简单的来说就是将客户端请求的 Query 语句(当然仅限于 SELECT 类型的 Query)通过一定的 has...

mysql中优化必读

通用规则多读少写加缓存,少读多写加队列带事务的不要整体commit,分段commit一、要保证数据库的效率,要做好以下四个方面的工作:① 数据库设计② sql语句优化③ 数据库参数配置④ 恰当的硬件资...

mysql常见面试题第一讲

一、为什么用自增列作为主键1、如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引。如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键...

innodb中内存管理机制BufferPool

innodb中内存管理机制BufferPool

内存结构InnoDB主索引是聚簇索引,索引与数据共用表空间,对于InnoDB而言,数据就是索引,索引就是数据。InnoDB缓存机制和MyISAM缓存机制的最大区别就是在于,InnoDB不仅仅是缓存索引...

mysql中排序和分页出现重复数据

场景我们使用分页查询时候经常会遇到需要对某个或者某几个字段进行排序,在排序字段有相同值的情况下有可能最后的排序结果不是我们预期的样子,我们来看下一个例子。表里面的rec_time列的数据是有重复的,一...

mysql中performance_schema(一)配置篇

背景    performance_schema最早在MYSQL 5.5中出现,而现在5.6,5.7中performance_schema又添加了更多的监控项,统计信息也...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。