三分钟小短文:一致性非锁定读与一致性锁定读

台上三分钟,台下三小时,兄弟们,今天咱们花三分钟了解下数据库中的两种读(select)操作: 一致性非锁定读一致性锁定读

一致性非锁定读

什么是一致的未锁定读取?在这里,我想给出一个最简单的解释:一致解锁的阅读就是阅读快照

[En]

What is a consistent unlocked read? Here I would like to give the most simple explanation: * consistent unlocked reading is reading snapshots * !

快照即当前行数据之前的历史版本,每行记录可能存在多个历史版本,或者说每行记录可能有不止一个快照数据,一般我们将这种技术称为 行多版本技术。而由于一个行记录可能对应着多个快照(历史版本),为此不可避免地会带来一系列的并发问题,如何解决这些并发问题,就是所谓的 多版本并发控制(MVCC),当然,这不是本文的重点。

在不同事务隔离级别下,读取的方式不同。只有在事务隔离级别 READ COMMITTED 和 REPEATABLE READ(默认)下,InnoDB 存储引擎才会使用非锁定的一致性读。并且,即使都是使用非锁定的一致性读,它俩 对于快照数据的定义也各不相同

  • 在 READ COMMITTED 事务隔离级别下,总是读取行的最新版本; 如果行被锁定了,非一致性读不会因此去等待行上锁的释放,而是去读取该行版本的最新一个快照,如下图所示: 三分钟小短文:一致性非锁定读与一致性锁定读
  • 在 REPEATABLE READ 事务隔离级别下,对于快照数据,非一致性读总是读取事务开始时的行数据版本

这么说可能还不是很好理解,举个例子,这个时候又得掏出我们经典的 user 表了(滑稽),表中包含三个字段 id、username、age,已存在一行记录:

id = 1, username = 'Jack', age = 20;

1)第一步,我们开启一个事务,执行如下语句:

事务 1:
    begin;
    select * from user where id = 1;

2)可以看到,第一个事务并没有提交,这时,我们开启第二个事务模拟并发,执行如下语句:

事务 2:
    begin;
    update user set id = 100 where id = 1;

3)在第二个事务中,将表中 id 为 1 的记录修改为了 id=100,但是事务同样没有提交(即此时 id = 1 的行记录被事务 2 加上了行锁)。这时如果在第一个事务中再次读取 id 为 1 的记录,那显然还是 1 对吧:

事务 1:
    select * from user where id = 1;

三分钟小短文:一致性非锁定读与一致性锁定读

4)接着,我们再来提交下第 2 个事务中所作的修改:

事务 2:
    commit;

由于当前 id = 1 的数据被修改成了 100,也就是说,当前 id = 100 的行记录拥有了一个 id = 1 的历史版本

三分钟小短文:一致性非锁定读与一致性锁定读

5)这个时候,再去事务 1 中读取 id 为 1 的记录,在 READ COMMITTED 和 REPEATABLE 事务隔离级别下得到结果就不一样了:

  • 对于 READ COMMITTED 的事务隔离级别,由于事务 2 已经提交了,也就是说 id = 1 的行记录没有被事务 2 锁定,所以就会去读取该行的最新版本,即 id = 100,So, 在 READ COMMITTED 的事务隔离级别下,此时查询 id = 1 的结果是 Empty Set;
  • 而在 REPEATABLE READ 事务隔离级别下,非一致性读总是读取事务开始时的行数据版本。也就是说,在事务 1 刚开始的时候,id = 1 的数据行是什么样,现在读到的就是什么样的: 三分钟小短文:一致性非锁定读与一致性锁定读

您可以结合下图查看上述流程:

[En]

You can review the above process in conjunction with the following figure:

三分钟小短文:一致性非锁定读与一致性锁定读

一致性锁定读

其实从名字上也能看出来,非一致性锁定读适用于对数据一致性要求不是很高的情况,比如在 READ COMMITTED 隔离级别下,即使行被锁定了,非一致性读也可以读到该行版本的最新一个快照。也即, 非锁定读机制极大地提高了数据库的并发性

一致性锁读适用于对数据一致性要求较高的场合,此时需要锁定读操作,以保证数据逻辑的一致性。

[En]

The consistency lock read is suitable for situations with high requirements for data consistency, at this time we need to lock the read operation to ensure the consistency of data logic.

InnoDB 存储引擎对读操作支持两种一致性锁定读方式,或者说对读操作支持两种加锁方式:

  • SELECT ... FOR UPDATE,对于读取的行记录加一个 X 排它锁,其他事务不能对锁定的行加任何锁
  • SELECT ... LOCK IN SHARE MODE,对于读取的行记录添加一个 S 共享锁。其它事务可以向被锁定的行加 S 锁,但是不允许添加 X 锁,否则会被阻塞住

So, 如何用大白话解释一致性锁定读?上面这两条特殊的 select 语句就是一致性锁定读!一致性锁定读就是给行记录加 X 锁或 S 锁!

简单不?

🎉 关注公众号 | 飞天小牛肉,即时获取更新

  • 博主东南大学硕士在读,携程 Java 后台开发暑期实习生,利用课余时间运营一个公众号『 飞天小牛肉 』,2020/12/29 日开通,专注分享计算机基础(数据结构 + 算法 + 计算机网络 + 数据库 + 操作系统 + Linux)、Java 技术栈等相关原创技术好文。本公众号的目的就是 让大家可以快速掌握重点知识,有的放矢。关注公众号第一时间获取文章更新,成长的路上我们一起进步
  • 并推荐个人维护的开源教程类项目: CS-Wiki(Gitee 推荐项目,现已累计 1.8k+ star), 致力打造完善的后端知识体系,在技术的路上少走弯路,欢迎各位小伙伴前来交流学习 ~ 😊
  • 如果各位小伙伴春招秋招没有拿得出手的项目的话,可以参考我写的一个项目「开源社区系统 Echo」Gitee 官方推荐项目,目前已累计 900+ star,基于 SpringBoot + MyBatis + MySQL + Redis + Kafka + Elasticsearch + Spring Security + … 并提供详细的开发文档和配套教程。公众号后台回复 Echo 可以获取配套教程,目前尚在更新中。

Original: https://www.cnblogs.com/cswiki/p/15307265.html
Author: 飞天小牛肉
Title: 三分钟小短文:一致性非锁定读与一致性锁定读

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/508128/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球