MySQL数据库---四种隔离级别详解

前言

· 这几天看了掘金的《从根上理解MySQL》对MySQL的理解像是打开了新世界的大门,强烈推荐给想进一步学习MySQL的兄弟们。大佬轻踩。
ps:貌似只有pdf版,需要电子资源的可百度可私信我。
pps:本文仅仅是对四大隔离级别及其底层实现做个概括,想详细了解的兄弟还是建议阅读《从根上理解MySQL》。

数据库的四大特性

在此之前有必要复习一下数据的大四特性:也就是ACID,化学里的酸~
· 原子性(Atomicity)
      指事务包含的操作要么全部成功,要么全部失败进行回滚。
· 一致性(Consistency)
      如果数据库中的数据全部符合现实世界的约束(all defined rules),我们说这些数据就是一致的,或者说是符合一致性的。
· 隔离性(Isolation)
      指多个用户并发访问数据库时,数据库为每个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
· 持久性(Durability)
      指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

并发场景下可能出现的问题

在认识四种隔离级别之前,我们要知道每种隔离级别是为了解决什么问题
· 脏写(Dirty Write)
      一个事务修改了另一个未提交事务修改过的数据
· 脏读(Dirty Read)
      一个事务读取了另一个未提交事务修改过的数据
· 不可重复读(Non-Repeatable Read)
      一个事务中,前后两次读取同一行的记录不一样。这个稍微难理解一点,直接看图吧,图是从其他地方来的,如侵立删。MySQL数据库---四种隔离级别详解_第1张图片
      这里可能会有疑问,既然另一个事务已经提交了,就应该读最新的值啊,好像不成问题啊。关于这个问题,我也不清楚,抱歉。也许会有特殊的场景需要满足不可重复读的情况,如果我知道了我会回来更新的。
· 幻读(Phantom)
      如果一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。
MySQL数据库---四种隔离级别详解_第2张图片
      形式上有点类似不可重复读,需要特别强调的是幻读针对的是前后两次读取,后面那一次读取读到了原本不存在的内容,如果是前后两次读取,后面那一次读取读的内容比原来少不算幻读。

四种隔离级别

终于进入了正题~
隔离级别的存在就是为了按照层次避免上面所描述的并发场景下可能出现的问题,这些问题也有轻重缓急之分,所以就设置了四种隔离级别,隔离级别越低,越严重的问题就越可能发生
· 按照出现问题的严重性排个序
      脏写 > 脏读 > 不可重复读 > 幻读
· SQL标准的四种隔离级别
      · read uncommited:未提交读
      · read commited:提交读
      · repeatable read:可重复读(这个级别主要解决了不可重复读的问题,所以称为可重复读,有够绕的。)
      · serializable:串行化
· SQL标准中各隔离级别可以避免的问题

隔离级别 脏读 不可重复读 幻读
read uncommited 不可避免 不可避免 不可避免
read commited 可避免 不可避免 不可避免
repeatable read 可避免 可避免 不可避免
serializable 可避免 可避免 可避免

      问:为什么没有脏写呢?因为脏写的问题太严重了,所以不论哪种级别,都不允许脏写的出现。
· 注意事项
      以上是SQL标准中的情况,MySQL支持以上四种隔离级别,但是在repeatable read级别上有点出入,那就是MySQL在repeatable read级别就可以避免幻读的发生了,且serialzable解决幻读的方法是对表中行最后加上间隙锁(gap lock),效率比较低。而repeatable read采用的是MVCC(多版本并发控制),是不用加锁的,效率比较高。所以实际应用中,repeatable read是最常用的隔离级别。
· 最后补充
      间隙锁和MVCC的概念比较多且略微复杂,由于篇幅原因,这里还是建议各位兄弟去阅读《从根上理解MySQL》。另外,不可重复读也可以用MVCC机制实现,只是细节上与解决幻读不同。

你可能感兴趣的:(数据库)