mysql可重复读概念_Mysql可重复读原理
概念
可重复读的实现
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可重复读原理相关推荐
- mysql自动提交的概念_MySQL入门之事务概念
MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过 set autocommit=0 禁止自动提交 set autocommit=1开启自动提交 mysql中INNOD ...
- mysql 可重复读 快照_MYSQL可重复读及原理、快照读和当前读
什么是可重复读 可重复读的实现 Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录(读已经提交的,其实是读早于本事务开始且已经提交的),但是不能看到 ...
- mysql可重复读 加锁_mysql可重复读隔离级别加锁分析
问题 myql可重复读隔离级别下可能会导致插入阻塞,问题复现如下 表中有3列都是int类型 其索引情况如下: id为主索引,c,d为普通索引 现在开始制作问题: 在这里我分别开启两个事务:第一个事务中 ...
- mysql可重复读实验_Mysql可重复读测试
mysql的InnoDB索引存储引擎在RR(REPEATABLE READ)隔离级别下读取的情况 测试建表 create table test_transaction ( id bigint(20) ...
- mysql全表重命名备份_MySQL数据库重命名的快速且安全方法(3种)
MySQL数据库重命名的方法 Innodb引擎的表如何改数据库名,MyISAM引擎又该如何操作. 如果表是MyISAM引擎可以直接去到数据库目录mv重命名文件夹就可以. Innodb完全不行,会提示相 ...
- mysql重设密码_MySQL之重设密码(忘记密码)讲解
Windows下的实际操作如下: 1.关闭正在运行的MySQL. 2.打开DOS窗口,转到mysql\bin目录. 3.输入mysqld(或mysqld-nt) --skip-grant-tables ...
- mysql中视图的概念_MySql中的视图的概念及应用
视图的基本概念 视图是从一个或几个基本表(或者视图)导出的表.它与基本表不同,是一个虚表. 数据库只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中.所以基本表中的数据发生变化, ...
- mysql最左前缀概念_mysql查询优化之目录类型、最左前缀
一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...
- mysql 表锁的概念_MySQL 锁的一些简单概念
1. 锁的粒度 在MySQL中,只要有多个请求需要在同一时刻修改数据,都会产生并发控制的问题.而锁的作用可以保证同一资源能被某个请求唯一使用. 加锁是会消耗系统资源的,包括获得锁.检查锁是否已解除.释 ...
最新文章
- PHP安装扩展mcrypt以及相关依赖项 【PHP安装PECL扩展的方法】
- docker,mysql,wordpress搭建个人博客
- UVA - 315 Network(tarjan求割点)
- 电大 计算机应用基础 专科 教材,2016年电大计算机应用基础(专科).doc
- git pull 报错:The following untracked working tree files would be overwritten by merge
- 【转】python的复制,深拷贝和浅拷贝的区别
- NOIP2013/day1/1/转圈游戏
- java integer 不变模式_《JAVA与模式》之不变模式
- 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛——F题 成绩查询ing
- VS2008中OGRE1.7.4下配置Hydrax-v0.5.1插件
- 我所认为的KVC和KVO
- android html文字垂直居中,Android EditText文本不是垂直居中的
- 2014手机号码归属地数据库
- 怎么把vivo强行刷入鸿蒙系统,vivo手机如何强制刷机
- SM3算法的编程实现
- 前端实现下载文件-js实现a标签下载
- 微型四轴飞行器(3)嵌入式软件设计
- 图片放大后失真不清晰,怎么办?
- SHoj 420 购买装备
- Spring各种注解 @PersistenceContext和@Resource @GetMapping、@PostMapping、@PutMapping、@DeleteMapping