首页 > 数据库 >【MySQL(八)】一致性非锁定读 锁定读 解析

【MySQL(八)】一致性非锁定读 锁定读 解析

时间:2022-11-11 12:40:11浏览次数:59  
标签:隔离 T2 update T1 MySQL 一致性 锁定 select


一致性非锁定读与锁定读的区别主要针对的是读操作在加锁方式上的差别。这里先看下锁的分类吧。

mysql的行锁分为读锁与写锁。

读锁即S锁,也叫共享锁,当事务读取一行数据时,会尝试在记录上加S锁;

写锁即X锁,也叫排它锁,当事务要更新或者删除一行数据时,会尝试在记录上加X锁;

只有S锁和S锁是互相兼容的,其余情况都是不兼容的,需要等待。

【MySQL(八)】一致性非锁定读  锁定读 解析_非锁定读

看这个表的意思,在读取时,需要先加S锁,实际上真的会吗?

答案是:否。

下面开始介绍锁定读与非锁定读。

非锁定读定义:​​https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html​

锁定读定义:​​https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html​

mysql官方的介绍还是比较全面的。

非锁定读全称是“Consistent Nonlocking Reads”,包含了两方面含义,一个是nonlocking,表明这种读操作不需要加S锁,所以即便其他事务已经在该数据行加了X锁,读操作仍然可以执行,不会阻塞。同样,一旦执行了读操作,其他事务仍然可以执行写操作,不会被阻塞。另一层含义是consistent,这个“一致性”取决于当前的隔离级别,在不同隔离级别下,读到的值是不同的。非锁定读可以保证即便其他事务修改了数据,但是当前读操作是不会被阻塞的,并且保证返回相应一致性要求下的快照数据。这个原理是由一种叫做MVCC的机制实现的。非锁定读是非序列化隔离级别下的默认读取方式。

锁定读全称是“Locking Read”,意味着当前的读操作需要先加锁(具体加什么锁取决于隔离级别和语法)。这样,如果当前记录已经有了X锁,那么读操作会阻塞。同样,一旦执行了读操作,其他事务的更新操作也会被阻塞。锁定读有如下几种方式:

1.在serializable隔离级别下,读操作加S锁;

2.非serializable隔离级别下使用select in share mode语法加S锁,使用select for update语法加X锁;

3.更新操作如update,insert以及delete,如果在语句中需要读,也是锁定读;

锁定读读到的肯定是最新的值;非锁定读是MVCC机制,取决于隔离级别;

这里顺便说一下select in share mode与select for update的用处。

简言之,select in share mode会加S锁,那么使用该语法,可以避免当前事务读取数据后,其他事务修改这一行数据。select for update会加X锁,那么使用该语法,可以避免当前事务读取数据后,其他事务也读取该行数据,这一点在防止更新覆盖时会非常有用,后面的博客会给出例子。

下面看几个例子:

1.serializable隔离级别下锁定读

T1:

【MySQL(八)】一致性非锁定读  锁定读 解析_非锁定读_02

T1先更新一条数据,上了X锁;

T2:

【MySQL(八)】一致性非锁定读  锁定读 解析_隔离级别_03

T2读取数据时,由于是锁定读,需要加S锁,于是发生了锁等待;

 

2.for update锁定读:

T1:

【MySQL(八)】一致性非锁定读  锁定读 解析_数据_04

T1先更新一条数据,上了X锁;

T2:

【MySQL(八)】一致性非锁定读  锁定读 解析_数据_05

T2读取数据,如果不写for update,那么由于是在repeatable read隔离级别下,使用的是非锁定读,是可以读的(见下面的例子);但是由于加了for update,就需要先上X锁,那么会锁等待。

 

3.不加for update会用非锁定读:

例子:

T1:

【MySQL(八)】一致性非锁定读  锁定读 解析_非锁定读_06

T1先更新一条数据,上了X锁;

T2:

【MySQL(八)】一致性非锁定读  锁定读 解析_数据_07

T2由于是非锁定读了,不需要加锁,所以仍然可以读取到数据,不会被阻塞。

 

4.select in share mode例子:

T1:

【MySQL(八)】一致性非锁定读  锁定读 解析_非锁定读_08

T2:

【MySQL(八)】一致性非锁定读  锁定读 解析_非锁定读_09

T2使用lock in share mode查询时,由于要加S锁,被阻塞。

 

小结:

锁定读与非锁定读的本质区别:读操作时是否需要加锁!!!

标签:隔离,T2,update,T1,MySQL,一致性,锁定,select
From: https://blog.51cto.com/u_15873544/5844583

相关文章

  • 【MySQL(三)】buffer pool相关
    bufferpool是一种减少磁盘io读的机制,原理是将访问过的磁盘数据暂留在内存中,这样下次访问相同的数据就不需要读磁盘了。这个思想在平时的开发中,也经常用到,比如我们通常会在......
  • 【MySQL(十九)】复制 过程
    主库将数据写入本地binlog文件中;从库连接,指定起始位置;主库的binlogdump线程开始将binlog内容发送给从库;从库的io线程将收到的binlog内容写入到本地的relaylog中;从库的sql......
  • MySQL启动报错[ERROR] InnoDB: Trying to access page number 4294967295 in space 0,
    这篇文章是原来的《记一次mysql故障处理》,但是随着mysql问题越来越多,我感觉还是集合到一篇里面比较好,也方便之后问题复现的查找一、记一次mysql故障处理最近遇到的问......
  • MySQL备库复制延迟的原因及解决办法【转】
    背景今天有同事问我主从复制延迟会影响高可用切换的RTO怎么办,这个不需要做实验,我可以直接回答,所以有了以下赶鸭子的文章,都是一线运维经验之谈,建议四连:点赞、收藏、转发......
  • 【mysql】索引
    mysql的索引是由引擎决定的。1.哈希索引,这个和哈希表是一样的原理,从关键字的哈希函数值映射到物理位置。特点是只能针对等于的查询,效率很高。2.B树索引,为关键字维护一棵b树,......
  • CentOS7 卸载 mysql8
    1、停掉mysql服务servicemysqlstop查看已安装的mysqlrpm-qa|grepmysql2、卸载mysql服务yumremovemysql-servermysqlmysql-libs再次查看是否还有......
  • MySQL复制表结构和内容到另一张表…
    1.复制表结构及数据到新表TABLE 新表SELECT * FROM 旧表2.只复制表结构到新表TABLE 新表SELECT * FROM 旧表 WHERE 1=2即:让WHERE条件不成立.方法二:(低版......
  • 12:企业规范约束-MySQL
    目录​​12.1★库表字段约束规范​​​​12.2索引规范​​​​12.3★SQL开发约束规范​​​​12.4其他规范​​12.1★库表字段约束规范字段名:​​is_vipunsignedtin......
  • 10:子查询-MySQL
    目录​​10.1子查询基本语法​​​​10.2in和notin​​​​10.3exists和notexists​​​​10.4基础结束语​​10.1子查询基本语法将一个查询的结果作为另一个查......
  • 11:高级部分-MySQL
    目录​​(一)view视图​​​​1.开场​​​​2.view视图创建、使用以及作用​​​​3.显示视图​​​​4.更新和删除视图​​​​5.视图算法:temptable,merge​​​​(......