文档章节

一致性非锁定读与一致性锁定读

Float_Luuu
 Float_Luuu
发布于 2016/12/12 00:17
字数 1203
阅读 635
收藏 1
点赞 0
评论 0

背景

innodb存储引擎实现了两种标准的行级锁:S锁和X锁,S锁被称为共享锁,允许事务读一行数据,X锁被称为排它锁,允许事务删除或更新一行数据。

一致性非锁定读指的是如果一条记录被加了X锁,其他事务还能读取这条记录。

一致性锁定读指的是一个事务可以通过SELECT语句给某条记录加X锁或者X锁。

一个小栗子

我们假设有一个表和两个事务,表名字为mytest,事务名字为t1和t2:

t1

t2

t3

t4

a bb bb ccc

t1和t2的执行时序如下:

t1

t2

 

begin;    
  begin;  
update mytest set t3='cc' where t2='bb';    
  select * from mytest where t2='bb'; Mark A
commit;    
  select * from mytest where t2='bb'; Mark B
  commit;  

这里我先抛出两个问题:

  1. 上面Mark A处显然t1已经给记录加了X锁,并且在事务内修改了数据,此时t2看到的数据是什么?
  2. 上面Mark B处事务t1已经提交此时t2看到的数据是什么?

行多版本控制

行多版本将的是innodb为每个行记录存储了多个版本,记住,这里是多个版本不是两个版本,在刚开始接触多版本的时候,我的疑问是innodb对每个行要存储多个版本是多么浪费存储空间呀?然而进一步了解,原来所谓的多版本只是innodb聪明地撒了个谎,多个版本是通过undo日志实现的,这里可以理解为既然undo日志包括了所有用来恢复历史版本数据的信息,那么我们只要将“不同版本”指针指向不同时间节点的undo日志即可,这样读取的时候通过对不同时间节点的undo日志进行恢复从而得到不同的版本数据。同时对于undo日志的读取是不需要加锁的,因此这极大地提高了数据库的并发性。

这里回答了上面的第一个问题:t2此时看到的应该是历史版本的数据,也就是t1修改之前的数据,如下:

mysql> select * from mytest where t2='bb';
+------+------+------+------+
| t1   | t2   | t3   | t4   |
+------+------+------+------+
| a    | bb   | bb   | ccc  |
+------+------+------+------+
1 row in set (0.00 sec)

 

READ COMMITTED 与 REPEATABLE READ

这里复习一下SQL标准定义的四个隔离级别分别为:

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

innodb默认的隔离级别为REPEATABLE READ且使用next key locking技术解决的幻读的问题,READ COMMITTED值的是一个事务可以读取其他事务已经提交的数据,而REPEATABLE READ要求一个事务在事务内可以重复读取一条记录,因此上面第二个问题的答案是此时t2看到的是什么跟此时数据库的隔离级别有关系,比如此时的隔离级别为:

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)

因此t2在Mark B的地方看到的应该是老数据:


mysql> select * from mytest where t2='bb';
+------+------+------+------+
| t1   | t2   | t3   | t4   |
+------+------+------+------+
| a    | bb   | bb   | ccc  |
+------+------+------+------+
1 row in set (0.00 sec)
mysql>

如果此时的事务隔离级别为READ COMMITTED,则t2在Mark B处看到的应该是新数据。

一致性锁定读

一致性非锁定读的情况下即使记录因为UPDATE而被加了X锁,其他事务仍然能够读取记录,不会阻塞。而如果一个事务希望在读取的时候就把记录锁住,不允许其他事务进行修改应该怎么做呢?那就是SELECT … FOR UPDATE,SELECT … FOR UPDATE显式地给一条记录加X锁,因此其他事务不能获取该记录的任何锁。我们也可以使用SELECT … LOCK IN SHARE MODE来给记录显式地加S锁,因此其他事务能够获取该记录的S锁而不能获取该记录的X锁,这两种语句都是有特定的应用场景的。

 

总结

再总结一下,一致性非锁定读讲的是一条记录被加了X锁其他事务仍然可以读而不被阻塞,是通过innodb的行多版本实现的,行多版本并不是实际存储多个版本记录而是通过undo实现。一致性锁定读讲的是我可以通过SELECT语句显式地给一条记录加X锁从而保证特定应用场景下的数据一致性。

© 著作权归作者所有

共有 人打赏支持
Float_Luuu
粉丝 198
博文 46
码字总数 102357
作品 0
长宁
高级程序员
InnoDB的锁定读与一致性非锁定读

InnoDB的锁定读与一致性非锁定读 本文主要介绍InnoDB的:锁定读和一致性非锁定读 锁定读(Locking Reads) 在一个事务中查询数据时,普通的SELECT语句不会对查询的数据进行加锁,其他事务仍可...

Gen_zhou ⋅ 2016/08/16 ⋅ 0

Mysql InnoDB锁机制

一、MySQL锁机制概述: (一)什么是锁,以及为什么使用锁和锁的运作? 锁是计算机协调多个进程或纯线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,...

皮蛋和 ⋅ 2017/12/31 ⋅ 0

MySQL事务隔离级别

MySQL事务隔离级别 事务就是一组原子性的sql查询,或者说一个独立的工作单元 事务内的语句,要么全部执行,要么全部执行失败 事务的ACID属性:原子性,一致性,隔离性,持久性 原子性:一个事...

秋风醉了 ⋅ 2014/04/02 ⋅ 0

数据库事务基础

一、概述 1.事务概念 在数据库中,事务是指一组逻辑工作单元执行的一系列动作,要么都执行,要么都不执行。 2.事务ACID特性 原子性(Atomic)原子性是指组成一个事务的多个数据库操作是一个不...

小米米儿小 ⋅ 2015/08/28 ⋅ 0

数据库事务及锁机制介绍

事务介绍 因为一直使用Spring这种声明式的事务管理,一直以为事务的主要作用是对一个业务方法中多次执行数据库操作的最终提交。近期重新了解了下事务,有了新的认识。数据库事务除了有异常回...

EveryDayNew ⋅ 2016/01/13 ⋅ 0

Oracle数据完整性和锁机制

本课内容属于Oracle高级课程范畴,内容略微偏向理论性,但是与数据库程序开发和管理、优化密切相关;另外本课的部分内容在前面章节已经涉及,请注意理论联系实际。 事务

linni ⋅ 2014/01/10 ⋅ 0

简单整理一下mysql的隔离级别;

READ UNCOMMITTED SELECT语句以非锁定方式被执行,但是一个可能更早期版本的记录会被用到。因此,使用这个隔离级别,比如,读是不连贯的。这也被称为“脏读”( dirty read)。另外,这个隔离...

世界和平维护者 ⋅ 2016/10/06 ⋅ 0

JAVA CAS原理深度分析

看了一堆文章,终于把JAVA CAS的原理深入分析清楚了。 感谢GOOGLE强大的搜索,借此挖苦下百度,依靠百度什么都学习不到! 参考文档: http://www.blogjava.net/xylz/archive/2010/07/04/3252...

serenity ⋅ 2015/08/10 ⋅ 0

并发编程(二)——JAVA CAS原理深度分析

看了一堆文章,终于把JAVA CAS的原理深入分析清楚了。 感谢GOOGLE强大的搜索,借此挖苦下百度,依靠百度什么都学习不到! 参考文档: http://www.blogjava.net/xylz/archive/2010/07/04/3252...

whc20011 ⋅ 2016/10/27 ⋅ 0

深入解析 volatile 、CAS 的实现原理

在分析说明 volatile 和 CAS 的实现原理前,我们需要先了解一些预备知识,这将是对 volatile 和 CAS 有深入理解的基石。 预备知识 缓存 现代处理器为了提高访问数据的效率,在每个CPU核心上都...

tomas家的小拨浪鼓 ⋅ 2017/12/11 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

实验楼—MySQL基础课程-挑战3实验报告

按照文档要求创建数据库 sudo sercice mysql startwget http://labfile.oss.aliyuncs.com/courses/9/createdb2.sqlvim /home/shiyanlou/createdb2.sql#查看下数据库代码 代码创建了grade......

zhangjin7 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部