概念

可重复读的实现

Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录(读已经提交的,其实是读早于本事务开始且已经提交的),但是不能看到其他事务对已有记录的更新(即晚于本事务开始的),并且,该事务不要求与其他事务是“可串行化”的。

这句话的核心,是“但是不能看到其他事务对已有记录的更新”,那么RR隔离级别是怎么保证这一点的呢?

实现原理

使用MVCC(多版本并发控制)。InnoDB为每行记录添加了一个版本号(系统版本号),每当修改数据时,版本号加一。

在读取事务开始时,系统会给事务一个当前版本号,事务会读取版本号<=当前版本号的数据,这时就算另一个事务插入一个数据,并立马提交,新插入这条数据的版本号会比读取事务的版本号高,因此读取事务读的数据还是不会变。

注意点

但是,当前事务想再写这行数据的话,还是以数据库提交的数据为准。并且会加行锁,其他的事务要再来修改的话,就得等到当前事务结束。

举例:

我们先看看现象,再分析原理。我的mysql版本是5.5。

下面是一张表,只有一条数据,并且我开启了事物

此时,另一个事物将record加1,因此我在开启一个命令行客户端,执行下面的命令:

成功加1之后,实际上,数据库中record肯定是2。

然后回到之前的客户端,再查一次:

没毛病,record还是1,果然是可重复读。有些人以为mysql的可重复读是通过行锁实现的,

从上面可以知道,肯定不是,如果是的话,第一次select * from test的时候,id=1的记录就会加行锁,我都加行锁了,我还没提交,另外的事物是怎么update成功的。

结论就是mysql使用的MVCC(多版本并发控制),MVCC详解可以看:https://blog.csdn.net/whoamiyang/article/details/51901888

我们继续,我之前的第一个事物还没提交,不过提交之前,我也想加1;

加完之后我再查一下,额,record是3,好像很奇怪,但也不奇怪。

其实,update test set record=record+1 where id=1;这条语句中,在加1之前,他知道自己等于2,然后2+1=3。

也就是说,update时读取数据是最新版本的数据,而select是到当前事物版本为止的数据。当更新成功之后,当前版本即为最新版本,再次select,读取的是最新的数据。

在这里讨论下乐观锁的必要性。下面是乐观锁的实现,实现乐观锁,我们一般会这么做

update test set record=record+1 where id=1 and record=1;

如果不用乐观锁,你用select读取到的值其实根本不准确。除非你开启悲观锁,像下面这样:

select * from test where id=1 for update;

这样可以读取到最新的内容,同时在你当前的事物提交之前,其他事物的update此条记录将会锁等待。

故事到此,还没有结束,此时我们开启事物三,也做加1操作看会发生什么。

结果是,锁等待超时,也就是说(事物一)在更新完后,会加行锁,这个应该比较好理解。事物中,刚开始查询的时候是不会加行锁的,但是当有更新操作之后,会加行锁,直到事物提交。

mysql可重复读概念_Mysql可重复读原理相关推荐

  1. mysql自动提交的概念_MySQL入门之事务概念

    MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过 set autocommit=0 禁止自动提交 set autocommit=1开启自动提交 mysql中INNOD ...

  2. mysql 可重复读 快照_MYSQL可重复读及原理、快照读和当前读

    什么是可重复读 可重复读的实现 Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录(读已经提交的,其实是读早于本事务开始且已经提交的),但是不能看到 ...

  3. mysql可重复读 加锁_mysql可重复读隔离级别加锁分析

    问题 myql可重复读隔离级别下可能会导致插入阻塞,问题复现如下 表中有3列都是int类型 其索引情况如下: id为主索引,c,d为普通索引 现在开始制作问题: 在这里我分别开启两个事务:第一个事务中 ...

  4. mysql可重复读实验_Mysql可重复读测试

    mysql的InnoDB索引存储引擎在RR(REPEATABLE READ)隔离级别下读取的情况 测试建表 create table test_transaction ( id bigint(20) ...

  5. mysql全表重命名备份_MySQL数据库重命名的快速且安全方法(3种)

    MySQL数据库重命名的方法 Innodb引擎的表如何改数据库名,MyISAM引擎又该如何操作. 如果表是MyISAM引擎可以直接去到数据库目录mv重命名文件夹就可以. Innodb完全不行,会提示相 ...

  6. mysql重设密码_MySQL之重设密码(忘记密码)讲解

    Windows下的实际操作如下: 1.关闭正在运行的MySQL. 2.打开DOS窗口,转到mysql\bin目录. 3.输入mysqld(或mysqld-nt) --skip-grant-tables ...

  7. mysql中视图的概念_MySql中的视图的概念及应用

    视图的基本概念 视图是从一个或几个基本表(或者视图)导出的表.它与基本表不同,是一个虚表. 数据库只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中.所以基本表中的数据发生变化, ...

  8. mysql最左前缀概念_mysql查询优化之目录类型、最左前缀

    一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...

  9. mysql 表锁的概念_MySQL 锁的一些简单概念

    1. 锁的粒度 在MySQL中,只要有多个请求需要在同一时刻修改数据,都会产生并发控制的问题.而锁的作用可以保证同一资源能被某个请求唯一使用. 加锁是会消耗系统资源的,包括获得锁.检查锁是否已解除.释 ...

最新文章

  1. PHP安装扩展mcrypt以及相关依赖项 【PHP安装PECL扩展的方法】
  2. docker,mysql,wordpress搭建个人博客
  3. UVA - 315 Network(tarjan求割点)
  4. 电大 计算机应用基础 专科 教材,2016年电大计算机应用基础(专科).doc
  5. git pull 报错:The following untracked working tree files would be overwritten by merge
  6. 【转】python的复制,深拷贝和浅拷贝的区别
  7. NOIP2013/day1/1/转圈游戏
  8. java integer 不变模式_《JAVA与模式》之不变模式
  9. 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛——F题 成绩查询ing
  10. VS2008中OGRE1.7.4下配置Hydrax-v0.5.1插件
  11. 我所认为的KVC和KVO
  12. android html文字垂直居中,Android EditText文本不是垂直居中的
  13. 2014手机号码归属地数据库
  14. 怎么把vivo强行刷入鸿蒙系统,vivo手机如何强制刷机
  15. SM3算法的编程实现
  16. 前端实现下载文件-js实现a标签下载
  17. 微型四轴飞行器(3)嵌入式软件设计
  18. 图片放大后失真不清晰,怎么办?
  19. SHoj 420 购买装备
  20. Spring各种注解 @PersistenceContext和@Resource @GetMapping、@PostMapping、@PutMapping、@DeleteMapping

热门文章

  1. 成都商业贷款买新房,取公积金流程
  2. linux下的扫描软件,4个用于Linux系统的扫描软件 - 爱绿豆
  3. windows资源管理器关闭了怎么打开
  4. xp系统开机密码忘了如何进入系统重新设置密码--win10专业版
  5. axure 授权码,试用期过了也可以用
  6. 加盐密码哈希:如何正确使用 (密码加密的经典文章)
  7. 蹲草丛-dfs或者bfs找最小的连着草丛i
  8. TEWA-600AEM天翼光猫超级管理员密码获取
  9. 广州银行冲刺A股上市:不良贷款规模突破100亿元,不良率飙升
  10. 工业加固三防平板主要适用于哪些环境