• 正文
    • RC(讀已提交)隔離級別
    • RR(可重復(fù)讀)隔離級別
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

RC和RR隔離級別下SELECT操作的讀取機(jī)制及差異

01/20 10:30
748
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

RC(讀已提交)和 RR(可重復(fù)讀)隔離級別下不同的查詢語句行為不同,讀取到的數(shù)據(jù)可能不同,以下是詳細(xì)分析:

RC(讀已提交)隔離級別

1. select?*?from table where id = 1?for update

讀取類型:不管是否在事務(wù)中執(zhí)行for update,這都是一種當(dāng)前讀,能確保讀取的數(shù)據(jù)是最新的,因?yàn)?for update 會對符合條件的記錄加排他鎖。

因?yàn)镽C級別下是每次執(zhí)行for update都會新生成讀視圖,事務(wù)每次執(zhí)行查詢操作,都會讀取最新已提交的數(shù)據(jù),可以讀到其他事務(wù)已提交的修改。

2. select?*?from table where id = 1:

讀取類型:快照讀(一致性讀),基于?MVCC讀視圖讀取的是事務(wù)開始時(shí)的快照版本。跟?for update一樣,可以看到其他事務(wù)已提交的修改。

當(dāng)where定位列id不是索引時(shí),需要進(jìn)行全表掃描,會涉及到回庫操作。對于?for update 語句,會對全表掃描到的符合條件的記錄加鎖,性能較差。對于普通的 select 語句,會根據(jù)MVCC機(jī)制,根據(jù)undo log版本鏈讀取相應(yīng)的事務(wù)版本數(shù)據(jù),雖然不加鎖但由于需要掃描全表,性能也會受到影響。

RR(可重復(fù)讀)隔離級別

1. select?*?from table where id = 1?for update

讀取類型:當(dāng)前讀。因?yàn)閒or update 對符合條件的記錄加鎖,確保讀取的數(shù)據(jù)是最新的,并且加鎖。

可以讀取到其他事務(wù)已提交的修改,在事務(wù)內(nèi),第一次執(zhí)行完?for update后,后續(xù)的?for update 讀取會看到相同的已修改結(jié)果,不會看到其他事務(wù)新的修改。因?yàn)榧渔i,其他事務(wù)無法修改,會阻塞或者報(bào)錯(cuò)。

與RR級別的區(qū)別,可以參考如下事務(wù):

begin;select?*?from?table?where?id?=?1?for?update;...select?*?from?table?where?id?=?1?for?update;commit;

如果是RC級別,第一次執(zhí)行for update時(shí)會對滿足id = 1 的記錄加鎖,如果?id 是主鍵或唯一索引,會加行鎖。當(dāng)該語句執(zhí)行完畢,鎖會被釋放,然后第二次執(zhí)行for update會繼續(xù)加鎖,那么兩次讀取之間就可能讀到其他事務(wù)已提交的修改內(nèi)容。

而RR級別第一次執(zhí)行for update時(shí)會對滿足 id = 1 的記錄加鎖,一直到事務(wù)結(jié)束。因此RR級別事務(wù)一致性較高,而性能較低。

2. select?*?from table where id = 1:

讀取類型:快照讀(一致性讀),基于事務(wù)開始時(shí)創(chuàng)建的快照進(jìn)行讀取。

只能讀取到事務(wù)開始時(shí)的數(shù)據(jù)快照,不能讀取到事務(wù)開始后其他事務(wù)已提交的修改,保證了在同一事務(wù)內(nèi)的可重復(fù)讀特性。

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄