MySQL事務隔離性

事務隔離性

當多個線程都開啓事務操做數據庫中數據時,數據庫系統要能進行隔離操做,以保證各個線程獲取數據的準確性。數據庫

若是沒有隔離,會發生的幾種問題

髒讀(Dirty Read)併發

一個事務處理過程裏讀取了另外一個未提交的事務中的數據性能

不可重複讀(NonRepeatable Read)spa

對於數據庫中的某個數據,一個事務範圍內屢次查詢卻返回了不一樣的數據值,這是因爲在查詢的間隔期間,另一個事務修改並提交了該數據。線程

不可重複讀和髒讀的區別是,髒讀是某一事務讀取了另外一個事務未提交的髒數據,而不可重複讀則是讀取了前一事務提交的數據。blog

在某些狀況下,不可重複讀並非問題,好比咱們屢次查詢某個數據固然以最後查詢獲得的結果爲主。但在另外一些狀況下就有可能發生問題,例如對於同一個數據A和B依次查詢就可能不一樣,A和B就可能打起來了……。索引

幻讀(Phantom Read)事務

在一個事務中讀取到了別的事務插入的數據,致使先後不一致。it

事務A 按照必定條件進行數據讀取,期間事務B插入了相同搜索條件的新數據,事務A再次按照原先條件進行讀取時,發現了事務B 新插入的數據。table

不一樣隔離級別的問題

MySQL的鎖類型

表鎖

對一整張表加鎖,併發能力低下(即便有分讀鎖、寫鎖),通常在DDL處理時使用,myisam也是表鎖。

行鎖

只鎖住特定行的數據,併發能力強,MySQL通常都是用行鎖來處理併發事務。

若是用到無索引的字段,那麼MySQL會在存儲引擎層面將全部的記錄加鎖,而後由MySQL Server過濾,若是不知足會調用unlock_row把不知足條件的記錄釋放鎖(這裏違背了二段鎖協議)。

這種狀況一樣適用於MySQL的默認隔離級別RR。因此對一個數據量很大的表作批量修改的時候,若是沒法使用相應的索引,MySQL Server過濾數據的的時候特別慢,就會出現雖然沒有修改某些行的數據,可是它們仍是被鎖住了的現象。

GAP鎖(間隙鎖)

MySQL使用索引對行鎖兩邊的區間進行加鎖,避免其餘事務在這兩個區間insert的一種鎖。

 

如圖所示:數據庫中存在值5,30。那麼數據庫會將數據段切分如下幾個區間:

(negative infinity, 5],

(5,30],

(30,positive infinity)

當對值爲30這一行加行鎖的時候,會同時對(5,30]和(30,positive infinity)加GAP鎖。這樣其餘事務若是想在這兩個區間進行insert操做的時候,須要等待本次事務完成。

若是對不存在的數據進行更新,好比更新20(不存在)對應數據行,那麼數據庫也會對其存在的區間(5,30]加GAP鎖。這樣,若是有其餘事務想插入值爲10的數據,須要等待20這個事務完成。

若是使用的是沒有索引的字段,那麼會給全表加入GAP鎖。

Next-Key鎖

Next-Key鎖是行鎖和GAP鎖的合併(MySQL使用它來避免幻讀)

MVVC(多版本併發控制)

Innodb中的樂觀鎖實現。經過它提升MySQL的讀取操做的性能。並能解決MySQL的重複讀問題。

MVVC在每一行記錄的後面加兩個隱含列(記錄建立版本號和刪除版本號)。這裏的版本號指的是事務的版本號(每一個事務啓動的時候,都有一個遞增的版本號)。

Innodb中事務隔離級別和鎖的關係

Innodb經過使用不一樣的鎖來實現事務隔離

避免髒讀

經過對數據加行鎖或則表鎖,使對同一數據進行操做的事務處於等待狀態,來避免同時操做

避免不可重複讀

經過MVVC實現事務的可重複讀

避免幻讀

經過Next-Key鎖避免產生幻讀現象。

MySQL在RC和RR中都避免了幻讀現象。

----------------------------------------------------------------------------------------------

悲觀鎖

樂觀鎖

在衝突比較少的時候採用樂觀鎖,減小不須要加鎖釋放鎖的開銷,能夠提升性能。

在衝突比較多的時候採用悲觀鎖,減小重複嘗試次數,樂觀鎖重複操做的代價比較大。

相關文章
相關標籤/搜索