在隔離級(jí)別中提到:
- 對(duì)于使用READ UNCOMMITTED隔離級(jí)別的事務(wù)來(lái)說(shuō),直接讀取記錄的最新版本就好了。
- 對(duì)于使用SERIALIZABLE隔離級(jí)別的事務(wù)來(lái)說(shuō),使用加鎖的方式來(lái)訪問(wèn)記錄。
- 對(duì)于使用READ COMMITTED和REPEATABLE READ隔離級(jí)別的事務(wù)來(lái)說(shuō),就需要通過(guò)ReadView追溯版本鏈。
核心問(wèn)題就是:需要判斷一下版本鏈中的哪個(gè)版本是當(dāng)前事務(wù)可見(jiàn)的。所以設(shè)計(jì)InnoDB的設(shè)計(jì)者提出了一個(gè)ReadView的概念,這個(gè)ReadView中主要包含當(dāng)前系統(tǒng)中還有哪些活躍的讀寫(xiě)事務(wù),把它們的事務(wù)id放到一個(gè)列表中,我們把這個(gè)列表命名為為m_ids。
這樣在訪問(wèn)某條記錄時(shí),只需要按照下邊的步驟判斷該記錄在版本鏈中的某個(gè)版本(trx_id)是否可見(jiàn):
- trx_id < m_ids列表中最小的事務(wù)id
表明生成該版本的事務(wù)在生成ReadView前已經(jīng)提交,所以該版本可以被當(dāng)前事務(wù)訪問(wèn)。 - trx_id > m_ids列表中最大的事務(wù)id
表明生成該版本的事務(wù)在生成ReadView 后才生成,所以該版本不可以被當(dāng)前事務(wù)訪問(wèn)。 - m_ids列表中最小的事務(wù)id < trx_id < m_ids列表中最大的事務(wù)id
(1)trx_id在m_ids中:說(shuō)明創(chuàng)建 ReadView 時(shí)生成該版本的事務(wù)還是活躍的,該版本不可以被訪問(wèn)。
(2)trx_id不在m_ids中:說(shuō)明創(chuàng)建 ReadView 時(shí)生成該版本的事務(wù)已經(jīng)被提交,該版本可以被訪問(wèn)。
如果某個(gè)版本的數(shù)據(jù)對(duì)當(dāng)前事務(wù)不可見(jiàn)的話,那就順著版本鏈找到下一個(gè)版本的數(shù)據(jù),繼續(xù)按照上邊的步驟判斷可見(jiàn)性,依此類(lèi)推,直到版本鏈中的最后一個(gè)版本,如果最后一個(gè)版本也不可見(jiàn)的話,那么就意味著該條記錄對(duì)該事務(wù)不可見(jiàn),查詢(xún)結(jié)果就不包含該記錄。