MySQL?RC事務(wù)隔離的實(shí)現(xiàn)原理
摘要:Read Committed事務(wù)運(yùn)行期間,只要?jiǎng)e的事務(wù)修改數(shù)據(jù)并提交,即可讀到人家修改的數(shù)據(jù),所以會(huì)有不可重復(fù)讀、幻讀問題。ReadView機(jī)制基于undo log版本鏈條實(shí)現(xiàn)的一套讀視圖機(jī)制,事務(wù)生成一個(gè)ReadView:若為事務(wù)自己更新的數(shù)據(jù),自己可以讀到或在你生成ReadView之前提交的事務(wù)所修改的值,也可讀到但若你生成ReadView時(shí),就已經(jīng)活躍的事務(wù),但如果它在你生成Read...
ReadView機(jī)制基于undo log版本鏈條實(shí)現(xiàn)的一套讀視圖機(jī)制,事務(wù)生成一個(gè)ReadView:
- 若為事務(wù)自己更新的數(shù)據(jù),自己可以讀到
- 或在你生成
ReadView之前提交的事務(wù)所修改的值,也可讀到 - 但若你生成
ReadView時(shí),就已經(jīng)活躍的事務(wù),但如果它在你生成ReadView之后修改的數(shù)據(jù)并提交了,此時(shí)你讀不到 - 或你生成
ReadView以后再開啟的事務(wù)修改了數(shù)據(jù),還提交了,也讀不到
所以上面那套機(jī)制就是ReadView的一個(gè)原理如何基于ReadView實(shí)現(xiàn)RC?核心設(shè)計(jì):當(dāng)一個(gè)事務(wù)設(shè)置RC,他是每次發(fā)起查詢,都重新生成一個(gè)ReadView!
數(shù)據(jù)庫(kù)里有一行數(shù)據(jù),是事務(wù)id=50的一個(gè)事務(wù),很久以前就插入的,當(dāng)前活躍事務(wù):
- 事務(wù)A(id=60)
- 事務(wù)B(id=70)
現(xiàn)在事務(wù)B發(fā)起update,更新這條數(shù)據(jù)為b,所以此時(shí)數(shù)據(jù)的trx_id會(huì)變?yōu)槭聞?wù)B的id=70,同時(shí)生成一條undo log:

這時(shí),事務(wù)A要發(fā)起一次查詢操作,就會(huì)生成一個(gè)ReadView

這時(shí)事務(wù)A發(fā)起查詢,發(fā)現(xiàn)當(dāng)前這條數(shù)據(jù)的trx_id=70。即屬于ReadView的事務(wù)id范圍之間,說(shuō)明是他生成ReadView之前就有這個(gè)活躍的事務(wù),是這個(gè)事務(wù)修改了這條數(shù)據(jù)的值,但此時(shí)事務(wù)B還沒提交,所以ReadView的m_ids活躍事務(wù)列表里,有[60, 70]兩個(gè)id,此時(shí)根據(jù)ReadView機(jī)制,事務(wù)A無(wú)法查到事務(wù)B修改的值b。
接著就順著undo log版本鏈條往下查找,就會(huì)找到一個(gè)原始值,發(fā)現(xiàn)其trx_id是50,小于當(dāng)前ReadView里的min_trx_id,說(shuō)明是他生成ReadView之前,就有一個(gè)事務(wù)插入了這個(gè)值并且早就提交了,因此可以查到這個(gè)原始值。
接著,假設(shè)事務(wù)B提交,提交了就說(shuō)明事務(wù)B不會(huì)活躍于數(shù)據(jù)庫(kù)里了。事務(wù)A下次再查詢,就可以讀到事務(wù)B修改過的值了。那到底是怎么讓事務(wù)A能夠讀到提交的事務(wù)B修改過的值呢?
讓事務(wù)A下次發(fā)起查詢,再生成一個(gè)ReadView,數(shù)據(jù)庫(kù)內(nèi)活躍的事務(wù)只有事務(wù)A,因此:
min_trx_id是60mac_trx_id是71m_ids=60,事務(wù)B的id=70不會(huì)出現(xiàn)在m_ids活躍事務(wù)列表
此時(shí)事務(wù)A再次基于這個(gè)ReadView去查詢,會(huì)發(fā)現(xiàn)這條數(shù)據(jù)的trx_id=70,雖然在ReadView的min_trx_id和max_trx_id范圍之間,但是此時(shí)并不在m_ids列表內(nèi),說(shuō)明事務(wù)B在生成本次ReadView之前就已提交。說(shuō)明這次你查詢就可以查到事務(wù)B修改過的這個(gè)值了, 此時(shí)事務(wù)A就會(huì)查到值B。
到此這篇關(guān)于MySQL RC事務(wù)隔離的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MySQL RC事務(wù)隔離內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL8.0移除傳統(tǒng)的.frm文件原因及解讀
MySQL 8.0移除傳統(tǒng)的.frm文件,采用基于InnoDB的事務(wù)型數(shù)據(jù)字典,主要解決了元數(shù)據(jù)不一致、性能優(yōu)化、架構(gòu)簡(jiǎn)化、增強(qiáng)功能支持、兼容性與升級(jí)問題,這一變革提高了數(shù)據(jù)庫(kù)的可靠性和性能,為未來(lái)的高級(jí)功能奠定了基礎(chǔ)2025-03-03
mysql中整數(shù)數(shù)據(jù)類型tinyint詳解
大家好,本篇文章主要講的是mysql中整數(shù)數(shù)據(jù)類型tinyint詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
mysql一對(duì)多關(guān)聯(lián)查詢分頁(yè)錯(cuò)誤問題的解決方法
這篇文章主要介紹了mysql一對(duì)多關(guān)聯(lián)查詢分頁(yè)錯(cuò)誤問題的解決方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09
解決mysql報(bào)錯(cuò)ERROR 1049 (42000): Unknown dat
對(duì)于錯(cuò)誤代碼1049(42000):Unknown database ‘?dāng)?shù)據(jù)庫(kù)‘,這個(gè)錯(cuò)誤通常表示您正在嘗試訪問一個(gè)不存在的數(shù)據(jù)庫(kù),本文給出了解決方法,您可以按照文中步驟進(jìn)行操作,需要的朋友可以參考下2024-01-01
IDEA鏈接MySQL報(bào)錯(cuò)08001和連接成功后不顯示表的問題及解決方法
這篇文章主要介紹了IDEA鏈接MySQL報(bào)錯(cuò)08001和連接成功后不顯示表的問題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10

