久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

數(shù)據(jù)庫的事務(wù)隔離級別怎么理解

137次閱讀
沒有評論

共計 2464 個字符,預(yù)計需要花費 7 分鐘才能閱讀完成。

本篇內(nèi)容主要講解“數(shù)據(jù)庫的事務(wù)隔離級別怎么理解”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“數(shù)據(jù)庫的事務(wù)隔離級別怎么理解”吧!

在 MVCC 并發(fā)控制中,讀操作可以分成兩類:快照讀 (snapshot read)與當前讀 (current read)。快照讀,某一時刻的一致性讀,不用加鎖。當前讀,讀取的是記錄的最新版本,并且,當前讀返回的記錄,都會加上鎖,保證其他事務(wù)不會再并發(fā)修改這條記錄。

MySQL 在 RR 隔離級別下,快照讀和當前讀如果在一個會話中先后出現(xiàn),可能會出現(xiàn)幻讀。因為快照讀不加鎖,會允許新的插入,當前讀需要讀到塊的最新版本,因此快照讀和當前讀兩次操作間,就可能會出現(xiàn)幻讀。 

MySQL 為實現(xiàn) RR 隔離級別,帶來了很大的代價,引入了 Next-Key Locking 解決當前讀模式下的幻讀問題。Next-Key Locking 可能會導(dǎo)致大量的 DML 失敗。Oracle 沒有 RR 隔離級別,在 read only 級別下,Oracle 沒有幻讀的問題(是快照讀的模式),在 read committed 級別下,快照讀、當前讀以及混合的【快照讀和當前讀】下都存在幻讀的問題。 

RR 隔離級別,MySQL 是依靠 MVCC 實現(xiàn)的可重復(fù)讀(read view),同時依靠 MVCC 實現(xiàn)快照讀下的幻讀問題,依靠 Next-Key Locking 實現(xiàn)當前讀下的幻讀問題,所以 MySQL InnoDB 的可重復(fù)讀并不保證避免幻讀,需要應(yīng)用顯式的使用加鎖讀來保證,而這個加鎖讀使用到的機制就是 next-key locks。

臟讀、不可重復(fù)讀、幻讀,是一種缺陷,越往后,解決缺陷的成本越高

隔離級別越高,能解決的“缺陷”越多,為什么不直接使用最高的事務(wù)隔離級別,那不就沒有缺陷了?因為隔離級別越高,并發(fā)性可能會越低。

臟讀,解決 寫不阻塞讀的問題,提高并發(fā)性,犧牲讀一致性?,F(xiàn)在絕大多數(shù)的主流數(shù)據(jù)庫,都是通過 MVCC 來解決寫不阻塞讀的問題,不是通過經(jīng)典的鎖來實現(xiàn)。

為什么會出現(xiàn)不可重復(fù)讀取? 
在經(jīng)典的 read commited 方式下,對于讀取過的數(shù)據(jù)并不加鎖(讀取的當下加共享鎖,讀取完成后釋放共享鎖),那么再次訪問時數(shù)據(jù)可能已經(jīng)被其他事務(wù)修改。

如何才能做到可重復(fù)讀? 
老一輩的數(shù)據(jù)庫藝術(shù)家用的方式是加鎖,對讀取過的數(shù)據(jù)加鎖,就能保證每一次讀取到的數(shù)據(jù)都是一樣的,因為對讀取過的數(shù)據(jù)加鎖后,數(shù)據(jù)無法發(fā)生修改了。這也是 repeatable read 這個隔離級別要解決的問題,但是經(jīng)典的實現(xiàn)可重復(fù)讀的方式會產(chǎn)生幻讀?,F(xiàn)在絕大多數(shù)的主流數(shù)據(jù)庫,是通過 MVCC 來做到的可重復(fù)讀,不是通過加鎖。

經(jīng)典的可重復(fù)讀提供了一個一致性(語句級和事務(wù)級)的讀取方式,雖存在幻讀,單從一致性的角度看,并不是一個大的缺陷,如果以經(jīng)典的鎖的方式去實現(xiàn)可重復(fù)讀,發(fā)生死鎖的概率極大,但帶來的一個(好的)副作用,解決了丟失更新的問題。

按照經(jīng)典的隔離級別定義,read uncommited,read commited,都不能提供一致性讀。因為當下主流數(shù)據(jù)庫都基于 MVCC 實現(xiàn),不基于經(jīng)典的鎖方式,所以都實現(xiàn)了在 read commited 級別下的語句級的一致性。經(jīng)典的隔離級別下,repeatable read 在語句級一致性的基礎(chǔ)上還做到了事務(wù)級的一致性。

針對 oracle 的隔離級別來說,read commited 級別能夠提供語句級的一致性,這個隔離級別避免不了事務(wù)級的幻讀的問題,需要 read only 或者最高的 SERIALIZABLE 級別。

在一個采用共享讀鎖(而不是多版本)的數(shù)據(jù)庫中,如果啟用了 REPEATABLE READ,可以避免丟失更新的問題。原因是:已被讀取的數(shù)據(jù)會在上面加一個鎖(共享讀鎖,非排它鎖),這個鎖會保證數(shù)據(jù)不能被任何其他事務(wù)修改。

在可重復(fù)讀(REPEATABLE READ,簡稱 RR)隔離級別下,read view 是在第一個讀請求發(fā)起時創(chuàng)建的。在讀已提交(READ COMMITTED,簡稱 RC)隔離級別下,則是在每次讀請求時都會重新創(chuàng)建一份 read view。根據(jù)上面提到的說法,RC 隔離級別下,是每次發(fā)起 SELECT 都會創(chuàng)建 read view,也就是每次 SELECT 都能讀取到本次查詢開始時的已經(jīng) commit 的數(shù)據(jù),所以才會出現(xiàn)不可重復(fù)讀、幻讀現(xiàn)象。

read view 判斷當前版本數(shù)據(jù)項是否可見  
在 innodb 中,創(chuàng)建一個新事務(wù)的時候,innodb 會將當前系統(tǒng)中的活躍事務(wù)列表(trx_sys- trx_list)創(chuàng)建一個副本(read view),副本中保存的是系統(tǒng)當前不應(yīng)該被本事務(wù)看到的其他事務(wù) id 列表。當用戶在這個事務(wù)中要讀取該行記錄的時候,innodb 會將該行當前的版本號與該 read view 進行比較。 
具體的算法如下: 

設(shè)該行的當前事務(wù) id 為 trx_id_0,read view 中最早的事務(wù) id 為 trx_id_1, 最遲的事務(wù) id 為 trx_id_2.

如果 trx_id_0 trx_id_1 的話,那么表明該行記錄所在的事務(wù)已經(jīng)在本次新事務(wù)創(chuàng)建之前就提交了,所以該行記錄的當前值是可見的。跳到步驟 6.

如果 trx_id_0 trx_id_2 的話,那么表明該行記錄所在的事務(wù)在本次新事務(wù)創(chuàng)建之后才開啟,所以該行記錄的當前值不可見. 跳到步驟 5。

如果 trx_id_1 =trx_id_0 =trx_id_2, 那么表明該行記錄所在事務(wù)在本次新事務(wù)創(chuàng)建的時候處于活動狀態(tài),從 trx_id_1 到 trx_id_2 進行遍歷,如果 trx_id_0 等于他們之中的某個事務(wù) id 的話,那么不可見。跳到步驟 5.

從該行記錄的 DB_ROLL_PTR 指針所指向的回滾段中取出最新的 undo-log 的版本號,將它賦值該 trx_id_0,然后跳到步驟 2.

將該可見行的值返回。

需要注意的是,新建事務(wù) (當前事務(wù)) 與正在內(nèi)存中 commit 的事務(wù)不在活躍事務(wù)鏈表中。

到此,相信大家對“數(shù)據(jù)庫的事務(wù)隔離級別怎么理解”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-07-18發(fā)表,共計2464字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 高邮市| 永德县| 台山市| 远安县| 西丰县| 宁德市| 红桥区| 清水河县| 浮山县| 潞城市| 手游| 河池市| 偃师市| 郎溪县| 克什克腾旗| 万全县| 上犹县| 舟曲县| 宁河县| 南平市| 克什克腾旗| 班戈县| 治县。| 宜昌市| 唐河县| 松阳县| 阳西县| 平远县| 嘉善县| 淮安市| 灵璧县| 清水河县| 苏尼特右旗| 刚察县| 璧山县| 札达县| 五河县| 安西县| 宁陵县| 丹棱县| 淮北市|