[MySQL-01] 阿里二面:了解 MySQL 事務(wù)底層原理嗎

原文鏈接

MySQL 可以說是每個(gè) Java 程序員必會(huì)的技能之一瓢谢,作為 Java 的高級(jí)進(jìn)階必備技能點(diǎn)模聋,MySQL 的調(diào)優(yōu)和底層原理必然是需要知道的。

但是大家似乎形成了一種思維定勢(shì)西土,那就是提到 MySQL 好像就一股腦的往 MySQL 的索引啊、優(yōu)化啊、之類的上面去鉆焚鲜。本文我們拋開“熱門”的話題垦页,來和大家一起來聊一聊比較冷門但比較重要的技術(shù)點(diǎn):MySQL 事務(wù)的底層原理

這事情還得從頭說起

首先大家需要知道的是 MySQL 是支持事務(wù)并發(fā)執(zhí)行的雀费,這又回到了最原始的問題了,「并發(fā)安全性問題」痊焊。在數(shù)據(jù)庫事務(wù)中并發(fā)問題是這樣子的:A 事務(wù)來寫某條記錄的數(shù)據(jù)盏袄,B 事務(wù)也在寫該條記錄的數(shù)據(jù)。那如果啥也不做薄啥,勢(shì)必會(huì)造成數(shù)據(jù)的錯(cuò)亂辕羽,MySQL 在設(shè)計(jì)之初就考慮到了這個(gè)問題。

那么 MySQL 到底是如何解決這樣的問題的呢垄惧?其實(shí)是使用了MVCC 多版本控制機(jī)制刁愿、事務(wù)隔離機(jī)制鎖機(jī)制等辦法來解決事務(wù)并發(fā)問題到逊。那說到這里不知道各位有沒有想過這樣一個(gè)問題:在數(shù)據(jù)庫中如果并發(fā)事務(wù)不做控制和處理铣口,會(huì)有什么樣的危害呢?

帶著這樣的疑問觉壶,請(qǐng)繼續(xù)往下看脑题。


臟數(shù)據(jù)

什么是臟數(shù)據(jù),它有哪些類型

臟數(shù)據(jù)的具體概念有以下四種铜靶,分別是:臟寫叔遂、臟讀、不可重復(fù)讀旷坦、幻讀掏熬。我們來看看這幾個(gè)概念的意思

1、臟寫

臟寫是指一個(gè)事務(wù)修改且已經(jīng)提交的數(shù)據(jù)被另外一個(gè)事務(wù)給回滾了

首先來分析一下概念:假設(shè)有兩個(gè)事務(wù) A秒梅、B旗芬。事務(wù) A 先開啟事務(wù),并且修改了一條 id 為 1 的記錄捆蜀,將 name 改成 A(假設(shè)原來為 null)疮丛,但是此時(shí) 事務(wù) A 還沒有提交幔嫂。這個(gè)時(shí)候事務(wù) B 開啟了。事務(wù) B 將 id 為 1 的記錄中 name 改成了 B誊薄,并且將事務(wù)提交 了履恩。但是這個(gè)時(shí)候事務(wù) A 不想修改了,就像之前自己修改的數(shù)據(jù)回滾了呢蔫。也就是說此時(shí)導(dǎo)致的結(jié)果就是 id 為 1 的這條記錄的 name 還是為 null切心。

然后事務(wù) B 去查詢這條記錄。結(jié)果蒙了片吊。name 居然為 null绽昏。這就是臟寫。事務(wù) B 已經(jīng)寫入的記錄被事務(wù) A 給回滾了俏脊。

看不懂沒有關(guān)系全谤,我們先來看一張圖

對(duì)著圖再來看一下上面的分析過程。

那 MySQL 是如何來解決臟寫這種問題的爷贫?沒錯(cuò)认然,就是。MySQL 在開啟一個(gè)事務(wù)的時(shí)候漫萄,他會(huì)將某條記錄和事務(wù)做一個(gè)綁定卷员。這個(gè)其實(shí)和 JVM 鎖是類似的。因?yàn)榇藭r(shí)事務(wù) A 先開啟了卷胯,并關(guān)聯(lián)綁定了這條記錄子刮。所以事務(wù) B 此時(shí)如果想操作同樣的記錄威酒,只能等待窑睁。當(dāng)事務(wù) A 執(zhí)行完成了,就會(huì)通知正在等在事務(wù)葵孤。然后下一個(gè)事務(wù)繼續(xù)操作執(zhí)行担钮。

啥?說好的并發(fā)尤仍,這說到底不還是串行嗎箫津?這樣數(shù)據(jù)庫豈不是慢的要死。實(shí)際上這些操作都是在內(nèi)存中執(zhí)行的宰啦。具體一點(diǎn)是在 Buffer Pool 中執(zhí)行的苏遥。所以速度是非常快的赡模。

2田炭、臟讀

臟讀是指一個(gè)事務(wù)讀取到了另外一個(gè)事務(wù)沒有提交的記錄

其實(shí)臟讀是最好理解的。我們還是假設(shè)有兩個(gè)事務(wù) A漓柑、B教硫。事務(wù) A 先開啟了叨吮,將 id 為 1 的記錄中的 name 改成了 A,但是還沒有提交瞬矩。此時(shí)事務(wù) B 開啟了茶鉴。事務(wù) B 查詢到當(dāng)前 name 的值為 A,然后就會(huì)按照 A 邏輯去執(zhí)行處理景用。結(jié)果事務(wù) A 回滾了事務(wù)涵叮,事務(wù) B 再次查詢的時(shí)候發(fā)現(xiàn)記錄值不是 A。這就是臟讀伞插。

事務(wù) B 讀取到的 name 值是事務(wù) A 修改但是沒有提交的記錄围肥。

來張圖來直觀的理解下:

3、不可重復(fù)讀

不可重復(fù)讀是指前后讀取到的某條記錄的結(jié)果不一樣

廢話少說蜂怎,直接進(jìn)分析:假設(shè)有三個(gè)事務(wù) A穆刻、B、C 杠步,事務(wù) A 先開啟了氢伟,但是還沒有執(zhí)行任何的操作,事務(wù) B 開啟了幽歼,事務(wù) B 將 id 為 1 的記錄的 name 改為 B 并提交了事務(wù)朵锣,此時(shí)事務(wù) A 開始活動(dòng)了,查詢到的這條記錄的 name 值為 B甸私,還是還未執(zhí)行任何操作诚些。此時(shí)事務(wù) C 開啟了,事務(wù) C 將 id 為 1 的記錄的 name 改為 C 并提交了事務(wù)皇型。此時(shí)事務(wù) A 又開始活動(dòng)了诬烹,結(jié)果查詢到的 id 為 1 的 name 值又變成了 C。這就是不可重復(fù)讀

其實(shí)理解起來還是很簡(jiǎn)單的弃鸦〗视酰看起來高大上名字,實(shí)際上就這么幾句話就能描述結(jié)束了唬格。下面還是來一張圖來更直觀認(rèn)識(shí)下:

4家破、幻讀

幻讀是指前后讀取到的記錄的數(shù)量不一樣

幻讀和不可重復(fù)讀有點(diǎn)類似,

不可重復(fù)讀強(qiáng)調(diào)的是數(shù)據(jù)的值不一樣购岗,重點(diǎn)是修改修改汰聋,
幻讀強(qiáng)調(diào)的是記錄的數(shù)量不一樣,重點(diǎn)是新增或刪除喊积。就好像是看花眼產(chǎn)生重影一樣烹困。

先來分析一下幻讀。還是假設(shè)有兩個(gè)事務(wù) A注服、B韭邓。事務(wù) A 先開啟了措近,并執(zhí)行了這樣的 SQL:select * from user,假設(shè)現(xiàn)在結(jié)果是 5 條女淑,此時(shí)事務(wù) B 開啟了瞭郑,并往 user 表中插入了一條記錄,并提交了事務(wù)鸭你,此時(shí)事務(wù) A 又執(zhí)行了 select * from user結(jié)果發(fā)現(xiàn)是 6 條記錄屈张。懵逼了。還以為自己餓昏了眼花了袱巨。這就是所謂的幻讀阁谆。

以上的四個(gè)問題是現(xiàn)代數(shù)據(jù)庫典型的問題,這些問題會(huì)在不同的數(shù)據(jù)庫的事務(wù)隔離級(jí)別下產(chǎn)生愉老。所以下面要分析的就是事務(wù)的隔離級(jí)別场绿。


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

事務(wù)的隔離級(jí)別有以下四種

  1. Read Uncommitted:讀取未提交【生產(chǎn)估計(jì)沒人這么設(shè)置的】
    意思就是一個(gè)事務(wù)能夠讀取到另一個(gè)事務(wù)未提交的修改
  2. Read Committed[簡(jiǎn)稱 RC]:讀取已提交
    意思就是一個(gè)事務(wù)能讀取到另一個(gè)事務(wù)已經(jīng)提交了的修改
  3. Repeatable read[簡(jiǎn)稱 RR]:可重復(fù)讀
    MySQL 的默認(rèn)隔離級(jí)別】,即事務(wù)之間只要是在進(jìn)行中嫉入,彼此之間不會(huì)有任何的干擾
  4. serializable:串行化
    這個(gè)就有點(diǎn)狠了焰盗,就好比 Java 中的 synchroinzed 關(guān)鍵字,所有的請(qǐng)求只能一個(gè)一個(gè)來還行咒林,很顯然效率最低熬拒,基本也不會(huì)使用這種隔離劑唄
隔離級(jí)別 臟讀 臟寫 不可重復(fù)讀 幻讀
Read Uncommitted:讀取未提交 ? × ? ?
Read Committed:讀取已提交 × × ? ?
Repeatable read:可重復(fù)讀 × × × ?
Serializable:串行化(也有稱序列化的) × × × ×

MVCC 機(jī)制

MVCC(全稱 Multi-Version Concurrency Control),即多版本并發(fā)控制垫竞。MVCC 是一種并發(fā)控制的方法澎粟,一般在數(shù)據(jù)庫管理系統(tǒng)中,實(shí)現(xiàn)對(duì)數(shù)據(jù)庫的并發(fā)訪問欢瞪;

我們本文的重點(diǎn)是事務(wù)的隔離級(jí)別的底層原理活烙,但是似乎說到現(xiàn)在也并沒有發(fā)現(xiàn)關(guān)于事務(wù)原理的影子

實(shí)際上要了解事務(wù)的底層原理,根本沒法上來就開魯引有,我相信那樣的文章寫出來不僅沒人看瓣颅,更是看不懂倦逐。所以為了讓大家由淺入深的慢慢掌握譬正。我必須要做很多鋪墊,將相關(guān)的知識(shí)點(diǎn)進(jìn)行拋磚引玉檬姥,然后一層一層剖析到原理曾我。這里還請(qǐng)大家明白。

說到這里健民,我們又要提到一個(gè)新的概念了抒巢。就是數(shù)據(jù)在磁盤存儲(chǔ)的時(shí)候,每一條存儲(chǔ)的記錄都會(huì)有事務(wù) ID 和回滾指針(其他的是什么本文不需要關(guān)注秉犹,學(xué)習(xí)抓住脈路即可蛉谜,否則必定走火入魔)稚晚。

這兩個(gè)到底是干嘛的?我們還是先從概念說起

事務(wù) ID:就是每個(gè)事務(wù)的唯一標(biāo)識(shí)
回滾指針:該事務(wù)之前的記錄的引用(指針)型诚。換句話說就是相對(duì)現(xiàn)在時(shí)間節(jié)點(diǎn)的老數(shù)據(jù)

假設(shè)你需要操作某條記錄,首先該條記錄一定是先被加載到 Buffer Pool 中的客燕,并且有這樣的一條 undo log 記錄。

畫外音:undo log 就是修改前的記錄狰贯。用于回滾的也搓。

假設(shè)現(xiàn)在事務(wù) A 開啟了事務(wù),將值改為 A

事務(wù) A 還在活躍中涵紊,這個(gè)時(shí)候事務(wù) B 開啟了傍妒,將值改為 B

此時(shí)事務(wù) A 和事務(wù) B 都還在活躍中,這個(gè)時(shí)候事務(wù) C 開啟了摸柄,并將值改為 C

看到這里是不是稍微有一點(diǎn)感覺了颤练。這上面的圖有一個(gè)專有名詞:MVCC 版本控制鏈。同時(shí)這里又涉及到一個(gè)新的名詞:ReadView驱负。就是每個(gè)事務(wù)在開啟的時(shí)候都會(huì)創(chuàng)建一個(gè) ReadView 視圖昔案。那具體什么叫 ReadView ,我們這里還不能一帶而過电媳,相反需要我們來詳細(xì)的討論分析下踏揣。

ReadView

ReadView 可能是你理解事務(wù)底層原理的核心部分,那么什么是 ReadView 呢

在每個(gè)事務(wù)開啟的時(shí)候都會(huì)創(chuàng)建一個(gè) ReadView 視圖匾乓,作用就是用來記錄每個(gè)事務(wù)中的操作的一些 Undo Log 記錄捞稿。

他里面涉及到幾個(gè)字段。分別是:m_ids拼缝、min_trx_id娱局、max_trx_idcreator_trx_id咧七。他們的具體含義如下:

  1. m_ids:用于記錄活躍中的事務(wù)的 ID衰齐;
  2. min_trx_id:當(dāng)前活躍的事務(wù)中的最小的事務(wù) ID;
  3. max_trx_id:下一個(gè)即將要生成的事務(wù) ID继阻。注意這里并不是指的最大的事務(wù) ID耻涛,這個(gè)事務(wù)一定是當(dāng)前的 m_ids 中不存在的。(事務(wù) ID 的生成是遞增的)瘟檩;
  4. creator_trx_id:當(dāng)前活躍事務(wù)的 ID抹缕;

不要慌,光說概念一定是在耍流氓墨辛。下面我會(huì)通過圖文并茂的形式來一一說明解釋卓研。假設(shè)有一個(gè)記錄現(xiàn)在是這樣存放的

看到這里大家應(yīng)該知道的是,這條記錄一定是原來的某一個(gè)事務(wù)修改后的結(jié)果。也就是說這是一條原本的已經(jīng)存在的記錄奏赘。

現(xiàn)在假設(shè)有 A寥闪、B、C 三個(gè)事務(wù)磨淌,他們分別先后開啟橙垢,假設(shè)他們的事務(wù) ID 依次為:4、5伦糯、6柜某。

先來看事務(wù) A,此時(shí)的m_ids 為:[4敛纲、5喂击、6],min_trx_id 為:4淤翔,max_trx_id 為 7翰绊,creator_trx_id 為 4。

事務(wù) A 首先執(zhí)行了一次查詢操作旁壮,他此時(shí)是這么執(zhí)行的:

首先他會(huì)順著 MVCC 的版本控制鏈往下找监嗜。找啥?找該條記錄的以前操作它的事務(wù) ID抡谐,他發(fā)現(xiàn)找到的這個(gè) undolog 日志的對(duì)應(yīng)的事務(wù) ID 為 3裁奇,比自己的 4 要小,所以可以肯定這條記錄不是自己修改的麦撵,而又因?yàn)?m_ids 中的事務(wù) ID 為 4刽肠、5、6免胃,3 是比他們都要小的音五,所以可推斷出查找到的這條記錄是在本次事務(wù)開啟之前就已經(jīng)存在的。所以事務(wù) A 查詢到的值為 C羔沙。

此時(shí)事務(wù) B 同樣開始查詢這條記錄了躺涝。以此類推事務(wù) B 此時(shí)的執(zhí)行流程大概是這樣子的,首先事務(wù) B 會(huì)以同樣的方式查詢數(shù)據(jù)(PS:這些操作都是在內(nèi)存中的)同樣查詢到的結(jié)果是 C扼雏,經(jīng)過上面的的對(duì)于事務(wù) A 的分析坚嗜,相信這里已經(jīng)不是問題了。但是假如現(xiàn)在事務(wù) B 將該值改成了 B呢蛤,也就是下面的這張圖的樣子惶傻。

此時(shí)事務(wù) A 又開始活躍了,還是執(zhí)行查詢操作其障,這個(gè)時(shí)候結(jié)果該是多少呢?

首先事務(wù) A 發(fā)現(xiàn)同樣會(huì)順著該條記錄的 MVCC 版本控制鏈往下找涂佃,發(fā)現(xiàn)事務(wù) ID 為 5 励翼,比 m_ids 中的最小的事務(wù) ID 4 要大蜈敢,那么可以且是存在于該集合中的,此時(shí)就可以斷定事務(wù) ID 為 5 的事務(wù)是正在進(jìn)行中的事務(wù)汽抚,所以事務(wù) A 是不會(huì)取該條 undo log 的值的抓狭。

然后繼續(xù)往下找,找到了事務(wù) ID 為 3 的 undo log 記錄造烁,對(duì)比后發(fā)現(xiàn) 3 不在 m_ids 中否过,且比 m_ids 中的最小的事務(wù) ID 都要小。下面的判斷就和剛開始的查詢判斷一樣了惭蟋。

假設(shè)此時(shí)事務(wù) A 將該條記錄的值改成 A 苗桂,然后事務(wù) A 再查詢這條記錄,那么請(qǐng)問這個(gè)時(shí)候事務(wù) A 查詢是怎么樣子的(這一步非常重要)告组?

那么事務(wù) A 到底是怎么查詢的煤伟?查出來的結(jié)果到底是 A 還是 B?先來看下這張圖木缝,然后根據(jù)圖一步一步來分析

事務(wù) A 開始查詢便锨,返現(xiàn)此時(shí)的 undo log 日志針對(duì)于該條記錄的 undo log 鏈(MVCC 版本鏈的另一種叫法)的第一條記錄的事務(wù) ID 為 4 ,一對(duì)比發(fā)現(xiàn)不就是自己修改的值嗎我碟?那么查詢的結(jié)果就是 A放案。

那么此時(shí)如果是事務(wù) B 來執(zhí)行查詢呢?結(jié)果你能否分析一下矫俺?那就是首先 B 發(fā)現(xiàn)最新的事務(wù) ID 為 4 卿叽,且在 m_ids 中,可以斷定這是一條正在執(zhí)行中的事務(wù)恳守,且不和自己的一樣考婴,所以是不會(huì)取該值的。

然后繼續(xù)順著 undo log 日志鏈往下找催烘,找到了事務(wù) ID 為 5 的記錄沥阱,發(fā)現(xiàn)和自己的一樣,那這個(gè)不就是需要查找的結(jié)果嗎伊群?也就是說 事務(wù) B 查找到的結(jié)果是 B考杉。

以上是關(guān)于 ReadView 的相關(guān)的介紹,總體內(nèi)容不算難舰始,但是是需要認(rèn)真思考的崇棠,這里先來一個(gè)小總結(jié)

ReadView 其實(shí)使用版本鏈機(jī)制

他里面的核心屬性為:

  1. m_ids: 一個(gè)列表, 存儲(chǔ)當(dāng)前系統(tǒng)活躍的事務(wù) id (重點(diǎn))
  2. min_trx_id: 當(dāng)前 m_ids 活動(dòng)事務(wù)中的最小的事務(wù) ID
  3. max_trx_id: 下一個(gè)即將被分配出來的事務(wù) ID
  4. creator_trx_id: 當(dāng)前的事務(wù)的 ID
  5. ReadView 記錄的是:每個(gè)事務(wù)中的 Undo log 日志

說到這里,下面繼續(xù)來分析本文的主題知識(shí)點(diǎn):事務(wù)的底層原理(其實(shí)上面多多少少都說到了)丸卷。其實(shí)事務(wù)的底層就是基于 ReadView 來設(shè)計(jì)的枕稀。關(guān)于事務(wù)的底層原理,我們以 RC(Read Commit)和 RR(Repeatable read)來分析

1. Read commit

Read Commit 是事務(wù)隔離級(jí)別的其中一種,含義是:讀取已經(jīng)提交的記錄萎坷。舉個(gè)例子來說凹联,假設(shè)有事務(wù) A 和事務(wù) B 都在活動(dòng)中,事務(wù) B 提交的記錄是能夠被事務(wù) A 讀取到的哆档。

具體我們開始一步一步來分析蔽挠。首先需要大家知道的是在 RC 隔離級(jí)別下,一個(gè)事務(wù)的每次查詢操作瓜浸,數(shù)據(jù)庫都會(huì)為其創(chuàng)建一個(gè)新的 ReadView澳淑,這就是 RC 的核心思想。

假設(shè)有事務(wù) A 和事務(wù) B 插佛,事務(wù) ID 分別為 10 和 11杠巡,事務(wù) A 還沒開始活躍,事務(wù) B 就將某條記錄的值改為 B(假設(shè)原來的值為 X)朗涩,但是還未提交忽孽,現(xiàn)在你可以想象一下下面這張圖:

此時(shí)事務(wù) A 開始活躍了,他首先執(zhí)行了一次查詢操作谢床。按照上面的核心思想兄一,此時(shí)數(shù)據(jù)庫會(huì)重新創(chuàng)建一個(gè) ReadView 里面的幾個(gè)屬性的值分別為:

  • m_ids:[10,11]
  • min_trx_id:10
  • max_trx_id: 12
  • creator_trx_id:10

接著就是就是和上面說過的一樣的查詢過程了,首先 A 查詢到的最近的一個(gè)事務(wù) ID 為 11识腿,發(fā)現(xiàn)在 m_ids 中出革,但是又和自己的事務(wù) ID 不相等,所以就會(huì)順著 undo log 鏈繼續(xù)查找渡讼,然后找到了事務(wù) ID 為 3 的記錄骂束,發(fā)現(xiàn)不在 m_ids 中且,比最小的事務(wù) ID 10 還要小成箫,所以可以斷定出事務(wù) ID 為 3 的這個(gè)記錄是原本就存在的記錄展箱,所以查詢到的結(jié)果就是 X。

接著事務(wù) B 又開始活躍了蹬昌,事務(wù) B 直接提交了事務(wù)混驰,然后事務(wù) A 又發(fā)起了一起查詢操作。現(xiàn)在這個(gè)時(shí)候就是 RC 的核心了:這個(gè)時(shí)候數(shù)據(jù)庫會(huì)再次為事務(wù) A 創(chuàng)建一個(gè)新的 ReadView 里面的四個(gè)屬性分別為:

  • m_ids:[10]
  • min_trx_id:10
  • max_trx_id: 12
  • creator_trx_id:10

然后 A 按照正常的流程去查詢皂贩,首先查詢到的是事務(wù) ID 為 11 的記錄栖榨,結(jié)果發(fā)現(xiàn)不在 m_ids 中,那這個(gè)時(shí)候就可以斷定的是:這個(gè)是最近已經(jīng)提交的記錄明刷,所以是能夠查詢到 B 這個(gè)值的婴栽,也就是說這次查詢得到的結(jié)果就是 B 。

這就是 RC辈末,是不是如果看懂了 ReadView 原理愚争,這些再看起來就非常簡(jiǎn)單了映皆?

2. Repeatable read

Repeatable read 是 MySQL 默認(rèn)的隔離級(jí)別,既然是默認(rèn)的准脂,那一定是很厲害咯劫扒?其實(shí)你看完會(huì)發(fā)現(xiàn) just so so ?

RR 的核心思想是:ReadView 創(chuàng)建以后直到事務(wù)提交檬洞,都不會(huì)再次重新生成狸膏。

首先還是有事務(wù) A 和事務(wù) B,事務(wù) ID 分別為 10 和 11 添怔,事務(wù) B 首先將值改為 B (假設(shè)原來值為 X)湾戳,然后 事務(wù) A 發(fā)起了一次查詢的操作:

查詢過程和前面的一模一樣。我就不再贅述了广料。

接著事務(wù) B 又開始活躍了砾脑,直接提交了事務(wù),然后事務(wù) A 又發(fā)起了一次查詢艾杏。這個(gè)時(shí)候奇跡就出現(xiàn)了韧衣。因?yàn)槲覀儎倓傉f了:ReadView 創(chuàng)建以后直到事務(wù)提交,都不會(huì)再次重新生成购桑。因?yàn)槭聞?wù) A 在創(chuàng)建 ReadView 的時(shí)候 m_ids 是 10 和 11畅铭,所以現(xiàn)在查詢的時(shí)候里面仍然是這個(gè)值,現(xiàn)在的查詢是這樣子的:事務(wù) A 首先查詢到的事務(wù) ID 為 11 勃蜘,結(jié)果發(fā)現(xiàn)在 m_ids 中硕噩,也就不會(huì)取該值,會(huì)繼續(xù)查找缭贡,當(dāng)查找到事務(wù) ID 為 3 的時(shí)候炉擅,發(fā)現(xiàn)不在 m_ids 中,所以查詢到的就是 X阳惹。

現(xiàn)在你知道為什么這個(gè)隔離級(jí)別下的事務(wù)不會(huì)互相干擾了吧谍失?這就是原理


本文小結(jié)

本文為了說明事務(wù)的底層原理,做了大量的鋪墊莹汤,相信大家看完不光對(duì)不同隔離級(jí)別下事務(wù)的實(shí)現(xiàn)會(huì)有更深刻地理解快鱼,也同時(shí)明白了 undo log 記錄的作用,所以多探索一下底層你會(huì)發(fā)現(xiàn)各種知識(shí)點(diǎn)是如何串在一起工作的体啰,這種通透的感覺確實(shí)很奇妙_


降溫了攒巍。。荒勇。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柒莉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子沽翔,更是在濱河造成了極大的恐慌兢孝,老刑警劉巖窿凤,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異跨蟹,居然都是意外死亡雳殊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門窗轩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夯秃,“玉大人,你說我怎么就攤上這事痢艺〔滞荩” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵堤舒,是天一觀的道長(zhǎng)色建。 經(jīng)常有香客問我,道長(zhǎng)舌缤,這世上最難降的妖魔是什么箕戳? 我笑而不...
    開封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮国撵,結(jié)果婚禮上陵吸,老公的妹妹穿的比我還像新娘。我一直安慰自己卸留,他們只是感情好走越,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耻瑟,像睡著了一般旨指。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喳整,一...
    開封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天谆构,我揣著相機(jī)與錄音,去河邊找鬼框都。 笑死搬素,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的魏保。 我是一名探鬼主播熬尺,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼谓罗!你這毒婦竟也來了粱哼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤檩咱,失蹤者是張志新(化名)和其女友劉穎揭措,沒想到半個(gè)月后胯舷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绊含,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年桑嘶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片躬充。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逃顶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出麻裳,到底是詐尸還是另有隱情口蝠,我是刑警寧澤器钟,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布津坑,位于F島的核電站,受9級(jí)特大地震影響傲霸,放射性物質(zhì)發(fā)生泄漏疆瑰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一昙啄、第九天 我趴在偏房一處隱蔽的房頂上張望穆役。 院中可真熱鬧,春花似錦梳凛、人聲如沸耿币。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淹接。三九已至,卻和暖如春叛溢,著一層夾襖步出監(jiān)牢的瞬間塑悼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工楷掉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厢蒜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓烹植,卻偏偏與公主長(zhǎng)得像斑鸦,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子草雕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

推薦閱讀更多精彩內(nèi)容