众所周知,在设定了隔离等级为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一致性读原来是有条件的的更多相关文章

  1. 差点掉坑,MySQL一致性读原来是有条件的

    众所周知,在设定了隔离等级为Repeatable Read及以上时,InnoDB 可以实现数据的一致性读.换句话来说,就是事务执行的任意时刻,读取到的数据是同一个快照,不会受到其他事务的更新影响. 以 ...

  2. [MySQL] 一致性读分析

    MySQL MVCC MySQL InnoDB存储引起实现的是基于多版本的并发控制协议---MVCC(Multi-Version Concurrency Control),基于锁的并发控制,Lock- ...

  3. MySQL 一致性读 深入研究

    一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文档:http://dev.mysql.com/doc/refman/5.6/en/innod ...

  4. MySQL 一致性读 深入研究 digdeep博客学习

    http://www.cnblogs.com/digdeep/p/4947694.html 一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文 ...

  5. mysql一致性读

    Consistent Nonlocking Reads 一致读意味着InnoDB用多版本来提供一个查询数据库某个时间点的快照.这种查询可以看到在当前世界点之前事务提交的改变,看不到此后提交的改变,更看 ...

  6. MySQL一致性非锁定读

    一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(multi versionning)的方式来读取当前执行时间数据库中行的数据,如果读取的行 ...

  7. MySQL的默认隔离级别的实现依赖于MVCC和锁,准确点说就是一致性读和锁。

    MySQL的默认隔离级别的实现依赖于MVCC和锁,准确点说就是一致性读和锁.

  8. MySQL——一致性非锁定读(快照读)&MVCC

    MySQL--一致性非锁定读(快照读) MySQL数据库中读分为一致性非锁定读.一致性锁定读 一致性非锁定读(快照读),普通的SELECT,通过多版本并发控制(MVCC)实现. 一致性锁定读(当前读) ...

  9. MySQL事务(二)事务隔离的实现原理:一致性读

    今天我们来学习一下MySQL的事务隔离是如何实现的.如果你对事务以及事务隔离级别还不太了解的话,这里左转. 好的,下面正式进入主题.事务隔离级别有4种:读未提交.读提交.可重复读和串行化.首先我们来说 ...

随机推荐

  1. 最佳实践 | 疫情之下,了解 eolink 如何助力远程办公!

    新冠疫情肆虐,eolink 结合自身长期的远程研发协作经验,为企业推出 API 管理远程协作指南,以下方案不仅在 Eolinker 内部,也在众多客户中得到验证,希望能够帮助您快速了解如何将 API ...

  2. java的访问权限protected和default

    protected和default的区别 第一点:在同一个包中,protected和default表现一致,即,当main方法所在的类和使用了protected与default修饰属性.方法的类在同一 ...

  3. 背包问题学习笔记 / Dynamic Programming(updating)

    01背包问题     朴素版:(二维数组) 状态表示: dp[i][j]:从前i个物品中选择(每个物品只能选0或1个)且总体积不超过j的集合的最大价值,则dp[n][m]就是最终答案(n:物品数量,m ...

  4. CF222C Reducing Fractions

    题目大意: 给出两个集合,第一个集合数的乘积是分子,第二个集合的数的乘积是分母,要求够造一个同样的集合,但是得到的分数是最简分数. 分析: 寻找思路并不复杂,对两个集合的每个数进行质因数分解,然后统计 ...

  5. PostgreSQL定时备份

    # PostgreSQL定时备份 # 版本:PostgreSQL14.0 # 一.如果你在pg_hba.conf中设定了密码登录,那么你就需要设置一个默认密码共psql登录的时候跳过验证.如果是roo ...

  6. 【Github开源项目体验】- ZFile 基于 Java 的在线网盘

    [Github开源项目体验]- ZFile 基于 Java 的在线网盘 在线云盘.网盘.OneDrive.云存储.私有云.对象存储.h5ai.上传.下载 date: 2022-08-02 addres ...

  7. 网络编程、OSI七层协议

    目录 软件开发架构 1.什么是软件开发架构 2.软件开发架构 3.架构优劣势 4.架构发展趋势 网络编程简介 1.如何理解网络编程 2.网络编程的目的 3.网络编程的意义 4.网络编程的起源 5.网络 ...

  8. SElinux管理

    SElinux: 是Linux的一个强制访问控制的安全模块 SElinux的相关概念: 对象:文件.目录.进程.端口等 主体:进程称为主体 SElinux将所有的文件都赋予一个type类型的标签,所有 ...

  9. 两天时间学习的html的知识笔记

    坚持努力背 特殊字符: 空格符  < 小于号 <> 大于号 >& 和号 &¥ 人民币 ¥  版权 ©R 注册商标 ®. 摄氏度 ° 正负号 ±X 乘号 × 除号 ...

  10. Java jdk常用工具集合

    jdk 常用工具包目录: windows: 默认安装目录:C:\Program Files\Java\jdk1.8.0_152\bin> 1.查看Java进程 jps -l 查看当前机器的Jav ...