自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

啥是 MySQL 事務(wù)隔離級(jí)別?

數(shù)據(jù)庫 MySQL
如果我們使用的 MySQL 存儲(chǔ)引擎為 InnoDB ,并且其事務(wù)隔離級(jí)別是 RR 可重復(fù)讀的話,是可以避免幻讀的。

[[413071]]

本文轉(zhuǎn)載自微信公眾號(hào)「SH的全棧筆記」,作者SH的全棧筆記。轉(zhuǎn)載本文請(qǐng)聯(lián)系SH的全棧筆記公眾號(hào)。

之前發(fā)過一篇文章,簡(jiǎn)單了解 MySQL 中相關(guān)的鎖,里面提到了,如果我們使用的 MySQL 存儲(chǔ)引擎為 InnoDB ,并且其事務(wù)隔離級(jí)別是 RR 可重復(fù)讀的話,是可以避免幻讀的。

但是沒想到,都 1202 年了都還有人杠,說 InnoDB 的 RR 隔離級(jí)別下會(huì)出現(xiàn)幻讀,只能依靠 gap 和 next-key 這兩個(gè)鎖來防止幻讀 ,最開始我還以為是他真的不知道這個(gè)點(diǎn),就跟他聊,最后聊下來發(fā)現(xiàn),發(fā)現(xiàn)是在鉆牛角尖。

這個(gè)在下面講到 可重復(fù)讀 的隔離級(jí)別時(shí)會(huì)講。

本來我覺得事務(wù)隔離級(jí)別這玩意兒太簡(jiǎn)單沒啥可講的,但是經(jīng)過了上面這件事,我打算詳細(xì)的把事務(wù)隔離給講講。接下來順便就把 InnoDB 所有的事務(wù)隔離級(jí)別給摟一遍。

ACID

在聊事務(wù)隔離級(jí)別之前,我們需要知道 ACID 模型。

ACID 模型

分別代表:

  • Atomicity 原子性
  • Consistency 一致性
  • Isolation 隔離型
  • Durability 持久性

原子性,代表 InnoDB 事務(wù)中,所有的操作要么全部成功,要么全部失敗,不會(huì)處于某個(gè)中間狀態(tài)。說的更通俗一點(diǎn),如果事務(wù) A 失敗,其所做的所有的更改應(yīng)該全部回滾。

一致性,主要是保護(hù)數(shù)據(jù)的一致性,防止由于數(shù)據(jù)庫的崩潰而導(dǎo)致的數(shù)據(jù)一致性問題。舉個(gè)例子,我們更新 MySQL 的數(shù)據(jù),更新的數(shù)據(jù)會(huì)先到 InnoDB 的 Buffer Pool 中,如果此時(shí) MySQL 所在的機(jī)器突然意外重啟了,如果 InnoDB 沒有崩潰恢復(fù)機(jī)制,之前更新的數(shù)據(jù)就會(huì)丟失,數(shù)據(jù)的一致性問題就出現(xiàn)了。

很多其他的博客寫的是事務(wù)開要始前后,數(shù)據(jù)的完整性沒有被破壞。我表示看了根本看不懂,太抽象了。

隔離性,主要是指事務(wù)之間的隔離,再具體一點(diǎn),就是我們本篇文章要討論的事務(wù)隔離級(jí)別了。

持久性,主要是指我們新增或者刪除了某些數(shù)據(jù),一旦成功,這些操作應(yīng)該需要被持久化到磁盤上去。

ACID 模型可以理解成數(shù)據(jù)庫的設(shè)計(jì)范式,主要關(guān)注點(diǎn)在數(shù)據(jù)數(shù)據(jù)、及其本身的可靠性。而 MySQL 中的 InnoDB 就完全遵守 ACID 模型,并且在存儲(chǔ)引擎層就支持?jǐn)?shù)據(jù)一致性的校驗(yàn)和崩潰恢復(fù)的機(jī)制。

而 ACID 中的隔離型,就是我們這篇文章中討論的重點(diǎn)。

事務(wù)隔離級(jí)別

有很多文章上來就直接介紹事務(wù)隔離級(jí)別的種類,這個(gè)種類啥意思,那個(gè)種類怎么用。但我認(rèn)為應(yīng)該先了解為什么需要事務(wù)隔離級(jí)別,以及事務(wù)隔離級(jí)別到底解決了什么問題,這才是關(guān)鍵。

我們知道 InnoDB 中同時(shí)會(huì)有多個(gè)事務(wù)對(duì)數(shù)據(jù)進(jìn)行操作,舉一些例子:

  • 假如事務(wù)A需要查詢 id=1 的數(shù)據(jù),但是事務(wù)A查詢完畢之后,事務(wù)B對(duì) id=1 的數(shù)據(jù)做了更新,那此時(shí)事務(wù)A再次執(zhí)行查詢,應(yīng)該看到更新前的數(shù)據(jù)還是更新后的數(shù)據(jù)?
  • 或者還是上面那個(gè)例子,事務(wù)A讀取了事務(wù)B的數(shù)據(jù),但是如果事務(wù)B進(jìn)行回滾了怎么辦?事務(wù)A的數(shù)據(jù)不就變成了臟數(shù)據(jù)?
  • 又或者事務(wù)A讀取了 1-3點(diǎn) 的日程安排,有4條,但是事務(wù)A讀取完成后事務(wù)B又向 1-3 點(diǎn)這個(gè)時(shí)間段插入了一條新的安排,那么事務(wù)A如果再次讀取,應(yīng)該顯示4條日程安排還是5條?

以上的這些問題,就需要事務(wù)隔離級(jí)別來回答了。其實(shí)以上的三種情況分別對(duì)應(yīng)不可重復(fù)讀、臟讀和幻讀。InnoDB 通過事務(wù)隔離級(jí)別分別的解決了上面的問題。所有的事務(wù)隔離級(jí)別如下:

  • READ UNCOMMITTED 讀未提交
  • READ COMMITTED 讀已提交
  • REPEATABLE READ 可重復(fù)讀
  • SERIALIZABLE 串行化

InnoDB 默認(rèn)的事務(wù)隔離級(jí)別為 REPEATABLE READ 。

讀未提交

事務(wù)A讀取了事務(wù)B還未提交的數(shù)據(jù)

如果事務(wù)B此時(shí)出錯(cuò)了進(jìn)行了回滾,那么事務(wù)A讀取到的數(shù)據(jù)就成為了臟數(shù)據(jù),從而造成臟讀。

如果事務(wù)B又更新事務(wù)A讀取的數(shù)據(jù),那么事務(wù)A再次讀取,讀取到了事務(wù)B修改的結(jié)果,這造成了不可重復(fù)讀。

而如果事務(wù)B又新增了數(shù)據(jù),事務(wù)A再次讀取,會(huì)讀取到事務(wù)B新增的數(shù)據(jù),這造成了幻讀。

所以總結(jié)來說,在讀未提交這個(gè)隔離級(jí)別下,會(huì)造成以下的問題:

  • 臟讀
  • 不可重復(fù)讀
  • 幻讀

讀已提交

事務(wù)A讀取了事務(wù)B已經(jīng)提交的數(shù)據(jù)

如果事務(wù)B更新了事務(wù)A讀取到的數(shù)據(jù),并且提交,那么當(dāng)事務(wù)A再次進(jìn)行讀取,就會(huì)讀取到其他事務(wù)的變更,就造成了不可重復(fù)讀。

同理,如果事務(wù)B新增了數(shù)據(jù)并且提交,事務(wù)A再次進(jìn)行讀取時(shí)拿到了事務(wù)B剛剛提交的數(shù)據(jù),這就造成了幻讀。

所以總結(jié)來說,在讀已提交的隔離級(jí)別下,會(huì)造成:

  • 不可重復(fù)讀
  • 幻讀

可重復(fù)讀

事務(wù)A不會(huì)讀取到事務(wù)B更新的數(shù)據(jù),也不會(huì)讀到事務(wù)B新增的數(shù)據(jù)

在可重復(fù)讀場(chǎng)景下,不會(huì)出現(xiàn)臟讀、不會(huì)出現(xiàn)不可重復(fù)讀,可能會(huì)出現(xiàn)幻讀。

無論事務(wù)B做了什么操作,事務(wù)A查詢到的 id=1 的數(shù)據(jù)都是張三。

但是,在某些情況下,還是可能會(huì)出現(xiàn) 幻讀??芍貜?fù)讀 只是在某些情況下會(huì)產(chǎn)生幻讀,但絕對(duì)不是 InnoDB 無法避免幻讀。首先,InnoDB 在 RR 隔離級(jí)別下有很明確的解決幻讀的方式,那就是——臨鍵鎖,一種組合了 gap 鎖和記錄鎖的鎖。

接下來舉個(gè)例子來看在 RR 隔離級(jí)別下,什么情況會(huì)出現(xiàn)幻讀,什么情況下不會(huì)出現(xiàn)幻讀。首先是 可能會(huì)出現(xiàn)幻讀。

  1. SELECT * FROM `student` WHERE `id` > 1 

由于 InnoDB 有 MVCC 來進(jìn)行多事務(wù)的并發(fā),此時(shí) SELECT 走的是快照讀,不會(huì)加鎖,那么臨鍵鎖就無法發(fā)揮其作用,如果有其他事務(wù)插入了一條數(shù)據(jù),那么事務(wù)再次執(zhí)行上面的語句是有可能會(huì)查出 id > 1 的數(shù)據(jù)。

但是如果顯示的進(jìn)行加鎖,則可以避免這個(gè)問題。

  1. SELECT * FROM `student` WHERE `id` > 1 FOR UPDATE 

至于為什么臨鍵鎖可以避免幻讀,之前的文章已經(jīng)聊的很清楚,就不在此贅述了。

串行化

所以事務(wù)被強(qiáng)制的串行執(zhí)行

這樣從根本上就避免了并發(fā)的問題,但是這樣會(huì)使得 MySQL 的性能下降。因?yàn)楝F(xiàn)在同一時(shí)間只能有一個(gè)事務(wù)在運(yùn)行。

EOF

關(guān)于事務(wù)隔離級(jí)別就先介紹到這,之后有時(shí)間了就把 事務(wù)隔離級(jí)別 的底層原理給摟一遍。

 

責(zé)任編輯:武曉燕 來源: SH的全棧筆記
相關(guān)推薦

2021-08-04 13:19:42

MySQL 事務(wù)隔離

2018-12-19 16:46:38

MySQL事務(wù)隔離數(shù)據(jù)庫

2024-04-26 09:17:20

MySQL事務(wù)隔離

2024-12-02 08:37:04

2010-11-19 16:13:06

oracle事務(wù)隔離級(jí)

2021-10-19 10:10:51

MySQL事務(wù)隔離級(jí)別數(shù)據(jù)庫

2009-06-29 17:54:47

Spring事務(wù)隔離

2025-03-03 08:20:00

MySQL事務(wù)隔離數(shù)據(jù)庫

2020-10-13 10:32:24

MySQL事務(wù)MVCC

2025-01-13 13:12:54

2022-06-10 11:51:49

MySQL事務(wù)隔離

2021-08-30 20:12:11

MySQL事務(wù)隔離

2021-01-18 11:49:26

面試事務(wù)隔離

2022-06-29 11:01:05

MySQL事務(wù)隔離級(jí)別

2022-09-13 13:49:05

數(shù)據(jù)庫隔離

2020-09-21 18:44:35

MySQL

2019-10-15 10:23:13

服務(wù)器MySQL 數(shù)據(jù)

2023-02-02 07:06:10

2024-07-16 08:19:46

MySQL數(shù)據(jù)InnoDB

2017-08-09 14:34:12

MysqlJavaPython
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)