談談MySQL中的鎖

談談MySQL中的鎖

鎖的定義

​ 在生活中鎖的例子就很是多了,因此應該很容易理解鎖的含義。在計算機領域,能夠這樣來概述,鎖是計算機協調多個進行進程併發訪問某一資源的機制。mysql

​ 在數據庫中,鎖也是一個很是重要的特性,DB的鎖是爲了支持對數據的併發訪問,保證數據的一致性以及處理統一數據時不破壞事務的隔離性和一致性。sql

鎖的機制

​ 從鎖的機制來看,大體可分爲樂觀鎖和悲觀鎖兩類。無論是樂觀鎖仍是悲觀鎖,他們是一種思想,而不是具體的鎖,並且不單單在數據庫系統中有這種概念。數據庫

樂觀鎖

老是假設最好的狀況,每次去拿數據的時候都認爲別人不會去修改,因此不上鎖。可是在更新數據的時候會判斷在這個期間這個數據有沒有被更新。併發

在mysql實際使用過程當中,有一種比較經常使用的實現方式:基於數據版本(vserion)記錄機制。每當數據更新一次,version自增長1。讀取數據記錄時,將version值讀出,當須要提交更新時,將判斷當前version值與讀出的值大小比較,若是一致,則進行更新,反之則說明過時,拒絕更新數據。code

悲觀鎖

老是假設最壞的狀況,每次拿數據的時候都認爲別人會修改,因此每次拿數據的時候就會上鎖,這樣其餘人想拿這個數據時就會阻塞,直到原來上鎖的進程釋放鎖。目前大多數數據庫普遍使用的鎖機制就是悲觀鎖思想,好比行鎖/表鎖/頁鎖等。下面會進行一些鎖的詳細講解。對象

悲觀鎖與樂觀鎖各有優勢,使用到的場景不一樣,樂觀鎖實用於多讀場景,而悲觀鎖適用於多寫場景。進程

鎖的粒度

相對其餘數據庫來講,Mysql的鎖比較簡單,但有一個特色,不一樣的存儲引擎支持不一樣鎖的粒度。事務

表鎖:顆粒度最大,鎖衝突的機率變大,併發度最低;開銷小,加鎖快,不會死鎖。資源

頁鎖:mysql特有的,粒度在表鎖與行鎖之間,因此獲取鎖資源的時間上,併發度上也是介於表鎖和行鎖之間,同時,頁鎖也會出現死鎖的狀況。io

行鎖:顆粒度最小,鎖衝突機率小,併發最高;開銷大,加鎖慢,容易死鎖。

表鎖適合以查詢爲主的業務,行鎖更適合於有併發更新少許數據且有併發查詢的業務。

不一樣引擎支持鎖的粒度

引擎 表鎖 頁鎖 行鎖
InnoDB ×
MyISAM × ×
BerkeleyDB × ×

鎖的類型

InnoDB存儲引擎還存在着不一樣類型的鎖,其中就包含下面兩種標準的行級鎖。

共享鎖 S:Shared Lock 讀鎖 容許事務去讀一行數據,阻止其餘事務得到相同數據集的排他鎖。

若事務T對數據對象A加上S鎖,則事務T能夠讀A但不能修改A,其餘事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這保證了其餘事務能夠讀A,但在T釋放A上的S鎖以前不能對A作任何修改。

排他鎖 X:Exclusive Lock,寫鎖 容許獲取排他鎖的事務更新數據,阻止其餘事務取得相同的數據集共享讀鎖和排他寫鎖 。

若事務T對數據對象A加上X鎖,事務T能夠讀A也能夠修改A,其餘事務不能再對A加任何鎖,直到T釋放A上的鎖。加過排他鎖的數據行在其餘事務種是不能修改數據的,也不能經過for update和lock in share mode鎖的方式查詢數據,但能夠直接經過select …from…查詢數據,由於普通查詢沒有任何鎖機制。

共享鎖 S 與 排他鎖 X 兼容性

鎖類型 S鎖 X鎖
S鎖 X
X鎖 X X

另外,爲了實現多粒度鎖機制,同時容許多粒度鎖機制,InnoDB還有兩種意向鎖,均爲表鎖。

意向共享鎖 IS: 事務打算給數據行共享鎖,事務在給一個數據行加共享鎖前必須先取得該表的IS鎖。 (表達一個事務想要獲取一張表中某幾行的共享鎖) 。

意向排他鎖 IX: 事務打算給數據行加排他鎖,事務在給一個數據行加排他鎖前必須先取得該表的IX鎖。( 表達一個事務想要獲取一張表中某幾行的排他鎖)。

意向共享鎖 S 與 意向 排他鎖 X 兼容性

鎖類型 IS IX S X
IS X
IX X X
S X X
X X X X X
相關文章
相關標籤/搜索