MySQL一致性读原来是有条件的
众所周知,在设定了隔离等级为Repeatable Read及以上时,InnoDB 可以实现数据的一致性读。换句话来说,就是事务执行的任意时刻,读取到的数据是同一个快照,不会受到其他事务的更新影响。
以前一直以为在事务内读到的数据不会受其他事务影响,后来发现只有普通的select语句才是一致性读。如果是update, delete, select for update, select in share mode等语句是当前读,读的是数据库最新数据, 下面是两个例子。
加锁读
创建一个测试用的表, 然后插入一条测试用的数据
create table test_innodb_read(
id int not null primary key,
value int
) engine = InnoDB charset=utf8;
insert into test_innodb_read values (1, 1);
当前autocommit和隔离等级如下
db83-3306>>select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
db83-3306>>select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
1 row in set (0.00 sec)
然后开启两个 Session,分别执行以下操作
| 时间点 | SessionA | 结果 | SessionB |
|---|---|---|---|
| 1 | begin select * from test_innodb_read where id=1 |
1 | |
| 2 | update test_innodb_read set value = 2 where id=1 |
||
| 3 | select * from test_innodb_read where id=1 |
1 | |
| 4 | select * from test_innodb_read where id=1 lock in share mode |
2 |
由于设置了自动提交,所以SessionB的更新语句执行完就已经提交了,从结果可以看到普通的Select不受其他事务影响,所以读到的数据都是同一版本,而在加锁读的情况下采取的是读最新的数据,所以读到的数据是最新提交的数据。
DML 操作
在进行数据变更操作的时候,也会拿到最新的数据,用的还是上面的表,插入一条测试数据
insert into test_innodb_read values (2, 1);
然后开启两个 Session,分别执行以下操作,
| 时间点 | SessionA | 结果 | SessionB |
|---|---|---|---|
| 1 | begin select * from test_innodb_read where id=2 |
1 | |
| 2 | update test_innodb_read set value = 2 where id=2 |
||
| 3 | select * from test_innodb_read where id=2 |
1 | |
| 4 | update test_innodb_read set value=value+1 where id=2 |
||
| 5 | select * from test_innodb_read where id=2 |
3 |
SessionA在时间点 5 查看数据拿到的是 3 而不是 2,原因是,事务在对数据进行更新操作时(时间点4),会先读取一次数据,这次读取的不是事务开始版本,而是数据的最新提交的值 2。如果不读取最新数据的话,就等于覆盖了SessionB的更新,所以读到的是 2,最后得到的数据是 3。
最后
当我知道这个知识点后,感觉背后一凉,以前写代码的时候,喜欢在事务里先把数据查出来,内存中相加减,再存库,现在想想这样做就是BUG啊,坑...
事务开始之后读取的只是事务开启时间点时该行记录的快照数据,只有当你要更新或者请求锁记录时才会获取到真实的行数据,因为行锁是针对真实行数据的,如果只是锁一个快照,那行锁就没有意义了,所以才会有悲观锁和乐观锁的概念出来
MySQL一致性读原来是有条件的的更多相关文章
- 差点掉坑,MySQL一致性读原来是有条件的
众所周知,在设定了隔离等级为Repeatable Read及以上时,InnoDB 可以实现数据的一致性读.换句话来说,就是事务执行的任意时刻,读取到的数据是同一个快照,不会受到其他事务的更新影响. 以 ...
- [MySQL] 一致性读分析
MySQL MVCC MySQL InnoDB存储引起实现的是基于多版本的并发控制协议---MVCC(Multi-Version Concurrency Control),基于锁的并发控制,Lock- ...
- MySQL 一致性读 深入研究
一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文档:http://dev.mysql.com/doc/refman/5.6/en/innod ...
- MySQL 一致性读 深入研究 digdeep博客学习
http://www.cnblogs.com/digdeep/p/4947694.html 一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文 ...
- mysql一致性读
Consistent Nonlocking Reads 一致读意味着InnoDB用多版本来提供一个查询数据库某个时间点的快照.这种查询可以看到在当前世界点之前事务提交的改变,看不到此后提交的改变,更看 ...
- MySQL一致性非锁定读
一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(multi versionning)的方式来读取当前执行时间数据库中行的数据,如果读取的行 ...
- MySQL的默认隔离级别的实现依赖于MVCC和锁,准确点说就是一致性读和锁。
MySQL的默认隔离级别的实现依赖于MVCC和锁,准确点说就是一致性读和锁.
- MySQL——一致性非锁定读(快照读)&MVCC
MySQL--一致性非锁定读(快照读) MySQL数据库中读分为一致性非锁定读.一致性锁定读 一致性非锁定读(快照读),普通的SELECT,通过多版本并发控制(MVCC)实现. 一致性锁定读(当前读) ...
- MySQL事务(二)事务隔离的实现原理:一致性读
今天我们来学习一下MySQL的事务隔离是如何实现的.如果你对事务以及事务隔离级别还不太了解的话,这里左转. 好的,下面正式进入主题.事务隔离级别有4种:读未提交.读提交.可重复读和串行化.首先我们来说 ...
随机推荐
- react antd上拉加载与下拉刷新与虚拟列表使用
创建项目 create-react-app antdReact 安装:antd-mobile.react-virtualized npm i antd-mobile -S npm i react-vi ...
- springboot集成swagger2报Illegal DefaultValue null for parameter type integer
springboot集成swagger2,实体类中有int类型,会报" Illegal DefaultValue null for parameter type integer"的 ...
- @Async注解的坑,小心
大家好,我是三友. 背景 前段时间,一个同事小姐姐跟我说她的项目起不来了,让我帮忙看一下,本着助人为乐的精神,这个忙肯定要去帮. 于是,我在她的控制台发现了如下的异常信息: Exception in ...
- CH341驱动安装
CH341驱动安装 参考文章:https://blog.csdn.net/qq_33194301/article/details/104510078 方法一: 下载驱动包,按提示编译,会出现下面报错 ...
- Re:用webpack从零开始的vue-cli搭建'生活'
有了vue-cli的帮助,我们创建vue的项目非常的方便,使用vue create然后选择些需要的配置项就能自动帮我们创建配置好的webpack项目脚手架了,实在是'居家旅行'必备良药.这次借着学习w ...
- elastsearch整合springboot
文档地址: https://www.baeldung.com/elasticsearch-java
- python主动杀死线程
简介 在一些项目中,为了防止影响主进程都会在执行一些耗时动作时采取多线程的方式,但是在开启线程后往往我们会需要快速的停止某个线程的动作,因此就需要进行强杀线程,下面将介绍两种杀死线程的方式. 直接强杀 ...
- Odoo14 OWL 如何访问model方法和res_id
首先OWL是Odoo14版本新加的功能. 因为是新加的所以并没有太多的说明文档,包括英文板文档也没有:所以你要用它再没有更详细的文档之前你得自己去看源码. 注意owl是没有do_action函数给你跳 ...
- rsync 文件备份
# rsync # 实现文件的备份. # 备份位置可以是当前主机,也可以是远程主机. # rsync实现了完全备份和增量备份 # 可以做到:1.将本地主机的文件复制到另一个位置(本地.远程). # 2 ...
- Taurus.MVC WebAPI 入门开发教程4:控制器方法及参数定义、获取及基础校验属性【Require】。
系列目录 1.Taurus.MVC WebAPI 入门开发教程1:框架下载环境配置与运行. 2.Taurus.MVC WebAPI 入门开发教程2:添加控制器输出Hello World. 3.Tau ...