【mysql】细说 数据库隔离级别 及实现

【mysql】细说 数据库隔离级别 及实现网上大多数关于隔离级别的文章都是讲了事务中的问题以及隔离级别可以解决的问题,我这次想看看数据库底层是如何实现隔离级别的。不过还是先来回顾一下隔离级别以及可能发生的问题。1.脏读:指的是一个事务的读操作读到了另一个未提交的事务修改的值。比如下面的场景:脏读的问题是,读到的值可能会被回滚,那么这个值就是失效的,不能继续使用,否则会有一致性问题。2.不可重复读:指的是一个事务读…

大家好,又见面了,我是你们的朋友全栈君。

网上大多数关于隔离级别的文章都是讲了事务中的问题以及隔离级别可以解决的问题,我这次想看看数据库底层是如何实现隔离级别的。

不过还是先来回顾一下隔离级别以及可能发生的问题。

1.脏读:指的是一个事务的读操作读到了另一个未提交的事务修改的值。比如下面的场景:

【mysql】细说 数据库隔离级别 及实现

脏读的问题是,读到的值可能会被回滚,那么这个值就是失效的,不能继续使用,否则会有一致性问题。

 

2.不可重复读:指的是一个事务读了同一个值两次,但是两次的值不同,因为中间另一个事务修改了这个值,比如下面的场景:

【mysql】细说 数据库隔离级别 及实现

t2事务是已提交的,所以t1的第二次读取是可以读到的。

 

3.幻读:仍然指的是一个事务中读了两次,结果不同,但是与不可重复读不同的是,这里不同是因为别的事物做了插入操作,而且读的条件是一个范围的条件,这样第二次会多读到一条数据,比如下面的例子:

【mysql】细说 数据库隔离级别 及实现

 

相应的有四种隔离级别,不同程度的解决了上面的问题:

【mysql】细说 数据库隔离级别 及实现

可以看到隔离界别越高,解决的问题就越多,但是并行化程度也越低,效率也越低。

 

那么数据库是如何实现隔离界别呢?下面以mysql innodb引擎来说下。事务隔离性,本质上解决事务的读写冲突的,在mysql中,读操作被实现为一种叫做“非锁定读取“的技术。什么意思,我们通常会说数据库里有共享锁和排它锁,读操作就是共享锁,只有共享锁和共享锁是非互斥的,那么如果一个读操作要在一个正在被修改的数据上进行,那么是无法加上获取该行对象的共享锁的,这便是数据库串行化隔离界别的实现方式,但是在其余的隔离界别下,我们不需要这么严格的隔离,我们允许了读操作可以在正在被修改的数据上即加上了排它锁的行数据上进行,这就是所谓的”非锁定读取“概念。

那么,读取的结果是什么?这个还需要明白另一点,就是我们数据库MVCC和undo日志,我们每一次的修改操作,并不是直接对行数据进行操作,比如我们设置id为3的行的A属性为10,并不是直接修改表中的数据,而是新加一行,同时数据表其实还有一些隐藏的属性,比如每一行的事务id,所以每一行数据可能会有多个版本,每一个修改过它的事务都会有一行,并且还会有关联的undo日志,表示这个操作原来的数据是什么,可以用它做回滚。那么为什么要这么做?因为如果我们直接把数据修改了,那么其他事务就用不了原先的值了,违反了事务的一致性。那么一个事务读取某一行的数据到底返回什么结果呢?取决于隔离级别,如果是Read Committed,那么返回的是最新的事务的提交值,所以未提交的事务修改的值是不会读到的,这就是Read Committed实现的原理。如果是Read Repeatable级别,那么只能返回发起时间比当前事务早的事务的提交值和比当前事务晚的删除事务删除的值。这其实就是MVCC方式。所以在第二个例子中,t2事务发生在t1后面,所以它更新的值是不会被t1读取到的,所以t1两次读取的值相同,也就是可以重复读。

关于可串行化的隔离界别,也很简单,严格的按照加锁协议来就可以,该级别可以避免上述所有的问题。

在oracle等数据库中,为了避免幻读,只能采用可串行化隔离级别,但是在innodb引擎中,在Repeatable Read级别也可以实现,主要是一种叫做”Next Locking“的技术,一种特殊的锁。

正常的锁一般是锁一行,称为是Record锁,而”Next Lock“则是锁一个范围内的行,比如说第三个例子中,t1事务第一次查询的是10到30之间的数据,那么最终这些数据都要被上锁,那么后面t2事务想要插入数据就不行了,会被拒绝,再往后,t1的第二次读取就会和第一次一样了。innodb采用这样的办法,就在repeatable read级别解决了幻读的问题。

最后总结一下innodb里面的锁的互斥,在可串行化级别,严格按照加锁协议,只有共享锁可以并行,其他全部阻塞。但是在其他的隔离级别,就放宽了很多。不过写-写是肯定不行的,读-读是肯定行的,读-写也是可以的,只不过读到什么内容就由MVCC来决定,由具体的隔离级别决定,写-读一般都可以,只有在启用了”Next Locking“的情况下会被拒绝。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141390.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 食品生物技术学计算机吗,食品生物技术「建议收藏」

    食品生物技术学计算机吗,食品生物技术「建议收藏」三、教学任务食品生物技术系主要承担本科生的课程如下:生物化学、微生物学、食品营养与卫生学、食品生物技术、实验设计与数据处理、综合性实验课等课程。承担生物化工和食品科学专业研究生高等生物化学、高等微生物学、实验动物学、现代生物技术等课程。四、主要研究方向与内容  食品生物技术系主要从事与食品生物技术方向的教学、科研及甜菜分子生物学方向的科研、研究生培养工作。1.食品分子营养与安全1.1食品分子营养学…

    2022年7月11日
    14
  • bitnami redmine mysql_Bitnami Redmine相关配置

    bitnami redmine mysql_Bitnami Redmine相关配置下载安装文件bitnami-redmine-3.3.1-0-linux-x64-installer.run官方下载链接:https://bitnami.com/stack/redmine/installer百度网盘链接:http://pan.baidu.com/s/1eRZsfmU密码:iorm一、给文件赋可执行权限。chmod777bitnami-redmine-3.3.1-0-linux…

    2025年6月9日
    0
  • C语言优先级 运算符

    C语言优先级 运算符1、最高级:出现同级别运算符时的结合方向是从左往右(下面级别没写结合顺序时,默认是从左往右)。()圆括号[]下标运算符号->指向结构体成员运算符.结构体成员运算符2、第二级:!、~、++、–、-、(类型)、*、&、sizeof。这一级都是单目运算符号,这一级的结合方向是从右向左。比如出现*p++,这时*和++同级别,先算右边,再左边。所以*p+…

    2022年6月16日
    36
  • linux phy调试方法_php执行shell命令

    linux phy调试方法_php执行shell命令enumphy_state{ PHY_DOWN=0, PHY_STARTING,//1 PHY_READY,//2 PHY_PENDING,//3 PHY_UP,//4 PHY_AN,//5 PHY_RUNNING,//6 PHY_NOLINK,//7 PHY_FORCING,//8 PHY_CHANGELINK,//9 PHY_HALTED,//10…

    2025年5月25日
    0
  • 小白能读懂的 《手把手教你学DSP(TMS320X281X)》第六章 使用c语言操作dsp寄存器(以SCI为例进行说明))

    小白能读懂的 《手把手教你学DSP(TMS320X281X)》第六章 使用c语言操作dsp寄存器(以SCI为例进行说明))1c语言与汇编语言器一些对时间要求特别高的时候需要嵌入一些汇编语言,其他时候使用c语言通过位定义和寄存器结构体的方式来实现对dsp寄存器进行访问和控制。2配置SCI寄存器2.1了解SCI寄存器前面我们讲过2812有两个SCI寄存器(SCIA和SCIB),可以做成两个串口(2RS232/2RS484/RS232+RS485)首先我们查看寄存器的寄存器文件以SCIA为例,第一列表示他有13个寄存器可以操作,并且都以SCI开头进行命名;第二列表示地址,即该寄存器所在的位置;后面

    2022年5月11日
    33

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号