Mysql事務隔離級別實現機制


MYSQL使用MVCC機制實現事務隔離,主要是通過構建一致性視圖來實現事務可見性隔離。我常說問題解決總是伴隨這新問題的產生,看看MVCC給我們帶來了那些有趣的思考吧。

在MySQL中默認隔離級別是RR(REPEATABLE-READ),RR隔離級別增加了間隙鎖,可以有效的避免幻讀,阻止不可重複讀。聽起來是不是感覺萬無一失了,其實不是這樣的,我們在工作中事務的聲明和加鎖是分多個階段執行的,這個很好理解。畢竟事務聲明後,可能要執行查詢更新等多個操作,總不能聲明事務的時候就直接加鎖吧,這個時候你也不知道爲哪一行記錄加鎖啊。但是這樣就造成了多個事務聲明後,由於不可重複的的原因,後生成的事務對記錄的變更對新事物不可見。通俗點說,A事務先於B事務聲明,此時如果A事務對記錄產生變更,那麼B事務無法讀取這個變更。到這裏就有必要談談MYSQL事務隔離實現機制MVCC和一致性視圖的問題了。

什麼是MVCC 機制


MVCC是多版本併發控制,Multiversion concurrency control,引用一段淘寶數據庫月報的解釋如下:

多版本控制: 指的是一種提高併發的技術。最早的數據庫系統,只有讀讀之間可以併發,讀寫,寫讀,寫寫都要阻塞。引入多版本之後,只有寫寫之間相互阻塞,其他三種操作都可以並行,這樣大幅度提高了InnoDB的併發度。在內部實現中,與Postgres在數據行上實現多版本不同,InnoDB是在undolog中實現的,通過undolog可以找回數據的歷史版本。找回的數據歷史版本可以提供給用戶讀(按照隔離級別的定義,有些讀請求只能看到比較老的數據版本),也可以在回滾的時候覆蓋數據頁上的數據。在InnoDB內部中,會記錄一個全局的活躍讀寫事務數組,其主要用來判斷事務的可見性。

從這段解釋,我們可以看到MCVV不僅提高了高併發,而且可以找回歷史版本。這一機制主要是依賴一致性視圖的構建。MySQL 會在事務開始後建立一個一致性視圖(並不是立刻建立),在這個視圖中,會保存所有活躍的事務(還未提交的事務)。一致性視圖解決不同事務之間可見性的問題,很通俗的大白話就是,記錄只在生成視圖前對事務可見。

聽起來挺好,但是問題是MYSQL不阻塞事務聲明提交,多個事務之間交叉聲明,這就導致新務無法讀取老事務對數據的更新。(如果事務可以串行執行就好了,不過這同時會帶來併發行問題)。由於這個是MYSQL內部實現機制,因此我們無法通過編程來解決,只能通過將事務隔離級別改爲RC,但是這同時也帶來數據脹讀問題。A事務更新記錄,導致B事務多次讀取記錄的結果不一致,幸運的是我們可以通過代碼解決數據髒讀的問題。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章