一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(multi versionning)的方式来读取当前执行时间数据库中行的数据,如果读取的行正在执行DELETE或UPDATE操作,这是读取操作不会因此等待行上锁的释放。相反的,InnoDB会去读取行的一个快照数据

上面展示了InnoDB存储引擎一致性的非锁定读。之所以称为非锁定读,因为不需要等待访问的行上X锁的释放

快照数据是指该行之前版本的数据,该实现是通过undo段来完成。而undo用来事务中的回滚数据,因此快照数据本身没有额外的开销,此外,读取快照数据不需要上锁,因为没有事务需要对历史数据进行修改操作

可以看到,非锁定读机制极大地提高了数据库的并发性,在InnoDB存储引擎的默认设置下,这是默认的读写方式,即读不会占用和等待表上的锁。但是在不同的事务隔离级别下,读取的方式不同,并不是每个事务隔离级别下都是采用非锁定的一致性读,此外,即使使用非锁定的一致性读,但是对于快照数据的定义也各不相同

快照其实是当前行数据之前的历史版本,每行记录可能有多个版本,如图显示,一个行记录可能有不止一个快照数据,一般称这种技术为多版本技术,因此带来的并发控制。称为多版本并发控制(Multi Version Concurrency Control,MVCC)

在事务隔离级别RC和RR下,InnoDB存储引擎引擎使用非锁定的一致性读。然而,对于快照数据的定义却不相同。在rc事务隔离级别下,对于快照数据,非一致性读总是被锁定行的最新一份快照数据.而在RR事务隔离级别下,对于快照数据,非一致性读总是读取事务开始时的行数据版本。

首先在MySQL的连接会话A中执行SQL语句

>BEGIN;

>SELECT * FROM parent where id=1;

会话A中已经显式的执行了BEGIN开启了一个事务,并读取了表parent中id为1的数据,但事务并没有结束。于此同时,用户开启另一个会话B,这样可以模拟并发的情况,然后对会话B做如下操作

>BEGIN;

>UPDATE parent SET id=3 WHERE id=1;

会话B中将表parent中ID为1的改成3,但是同样事务没有提交,这样id=1的行其实加了一个X锁。这时如果在会话A中再次读取id为1的记录,根据InnoDB存储引擎的特性,即在RC和RR事务隔离级别下会使用非锁定的一致性读。回到之前的会话A,接着上次未提交的事务,执行SQL语句SELECT * FROM parent WHERE id=1操作,这时不管是RC还是RR,显示的数据都是1

由于当前id=1的数据被修改了1次,因此只有一个行版本的记录,接着在会话B中提交上次的事务

>commint;

在会话B提交事务后,A中再次运行SELECT * FROM parent WHERE id=1,在RC和RR的事务隔离级别下得到的结果就不一样了。在RC事务隔离级别,它总是读取行的最新版本,如果行被锁定,则读取该行版本的最新一个快照(fresh snapshot)在上述例子中,因为B已经提交了事务,所以在RC隔离级别下的结果是

>select @@tx_isolation; 查看当前事务隔离级别

> SELECT * FROM parent WHERE id=1  结果为空

而对于RR隔离级别,总是读取事务开始时的行数据,因此,对于RR事务隔离级别,得到的结果是

>select @@tx_isolation; 查看当前事务隔离级别

> SELECT * FROM parent WHERE id=1  结果为1

MySQL中一致性非锁定读的更多相关文章

  1. MySQL一致性非锁定读

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

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

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

  3. 14.3.2.3 Consistent Nonlocking Reads 一致性非锁定读

    14.3.2.3 Consistent Nonlocking Reads 一致性非锁定读 一致性读 意味着 InnoDB 使用多版本来保护查询一个数据库在当前时间点的快照. 查询看到被事务做出的修改, ...

  4. 14.5.2.3 Consistent Nonlocking Reads 一致性非锁定读

    14.5.2.3 Consistent Nonlocking Reads 一致性非锁定读 一致性读意味着 InnoDB 使用多版本来实现一个查询数据库的快照在某个时间点. 查看看到的事务做出的改变被提 ...

  5. MySQL中的幻读,你真的理解吗?

    昨天接到阿里的电话面试,对方问了一个在MySQL当中,什么是幻读.当时一脸懵逼,凭着印象和对方胡扯了几句.面试结束后,赶紧去查资料,才发现之前对幻读的理解完全错误.下面,我们就聊聊幻读. 要说幻读,就 ...

  6. mysql中的意向锁IS,IX

    知识储备: 1.官方文档上说mysql是支持非锁定读的:这个功能是这样实现的,如果事务a 要对行的数据进行更新的话,那么事务a要得到行的x锁,并把这一行  之前的样子记录在undo log里面,这样一 ...

  7. MySQL中的 redo 日志文件

    MySQL中的 redo 日志文件 MySQL中有三种日志文件,redo log.bin log.undo log.redo log 是 存储引擎层(innodb)生成的日志,主要为了保证数据的可靠性 ...

  8. 一步一步学MySQL-一致性非锁定读和锁定读

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

  9. 别再误解MySQL和「幻读」了

    The so-called phantom problem occurs within a transaction when the same query produces different set ...

随机推荐

  1. sqlserver用户角色相关的权限

  2. destoon二次开发基础指南

    代码首先包含common.inc.php文件 在common.inc.php文件中,首先定义常量. define('IN_DESTOON', true); define('IN_ADMIN', def ...

  3. Blocking & Nonblocking module

    /*************************************************** /  Blocking and Nonblocking circuit and Simulat ...

  4. [ci] 构建触发器,实现当gitlab有push动作时候,jenkins自动拉代码.

    构建触发器,实现当gitlab有push动作时候,jenkins自动拉代码. 拉取gitlab代码库: jenkins安装git插件 配置gitlab服务器和jenkins服务器身份互信 jenkin ...

  5. Codeforces Round #277 (Div. 2)---A. Calculating Function (规律)

    Calculating Function time limit per test 1 second memory limit per test 256 megabytes input standard ...

  6. 170. Two Sum III - Data structure design【easy】

    170. Two Sum III - Data structure design[easy] Design and implement a TwoSum class. It should suppor ...

  7. JavaScript之语句

    ECMA-262 规定了一组语句(也称为流控制语句).从本质上看,语句定义了 ECMAScript 中的主要语法,语句通常使用一或多个关键字来完成给定任务. if语句 if语句是最常见的一种语句,语法 ...

  8. 浅谈一致性hash

    相信做过互联网应用的都知道,如何很好的做到横向扩展,其实是个蛮难的话题,缓存可横向扩展,如果采用简单的取模,余数方式的部署,基本是无法做到后期的扩展的,数据迁移及分布都是问题,举个例子: 假设采用取模 ...

  9. c++ [wrong]simple "Garbage Collector"

    In fact, Ptr alone can accomplish the task mentioned below. Implementation see Ptr.h, main2.cpp. In ...

  10. 解决Eclipse的dropins中svn插件不能加载的问题

    在eclipse的dropins中我们将svn的插件放到里边重启我们的ecplise就能正常加载svn插件了,如下图 但是有时候我们删除了svn的项目之后有可能我们的eclipse就不能正常加载svn ...