1、鎖的分類
1.1從對數據操作的類型來分
讀鎖(共享鎖):針對同一份數據,多個讀操作可以同時進行而不會互相影響。
結論1:
--如果某一個會話 對A表加了read鎖,則 該會話 可以對A表進行讀操作、不能進行寫操作; 且 該會話不能對其他表進行讀、寫操作。
--即如果給A表加了讀鎖,則當前會話只能對A表進行讀操作。
結論2:
會話0給A表加了鎖;其他會話的操作:a.可以對其他表(A表以外的表)進行讀、寫操作
b.對A表:讀-可以; 寫-需要等待釋放鎖。、
某回話給某個表加了讀鎖,所有的回話都能對該表進行讀操作,不能進行寫操作,除非該會話釋放讀鎖。
寫鎖(排它鎖):當前寫操作沒有完成前,它會阻斷其他寫鎖和讀鎖。
當前會話(會話0) 可以對加了寫鎖的表 進行任何操作(增刪改查);但是不能 操作(增刪改查)其他表
其他會話:對會話0中加寫鎖的表 可以進行增刪改查的前提是:等待會話0釋放寫鎖
2.2從鎖粒度划分。
一般分為:行鎖、表鎖、庫鎖
(1)行鎖:訪問數據庫的時候,鎖定整個行數據,防止並發錯誤。 如InnoDB存儲引擎使用行鎖
(2)表鎖:訪問數據庫的時候,鎖定整個表數據,防止並發錯誤。 如MyISAM存儲引擎使用表鎖
行鎖 和 表鎖 的區別:
- 表鎖: 開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突概率高,並發度最低
- 行鎖: 開銷大,加鎖慢;會出現死鎖;鎖定粒度小,發生鎖沖突的概率低,並發度高
2. 3 補充 悲觀鎖 和 樂觀鎖
(1)悲觀鎖:顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關系型數據庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
(2)樂觀鎖: 顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量,像數據庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。
(3)悲觀鎖 和 樂觀鎖的區別:
- 樂觀鎖在不發生取鎖失敗的情況下開銷比悲觀鎖小,但是一旦發生失敗回滾開銷則比較大,因此適合用在取鎖失敗概率比較小的場景,可以提升系統並發性能
- 樂觀鎖還適用於一些比較特殊的場景,例如在業務操作過程中無法和數據庫保持連接等悲觀鎖無法適用的地方
小結:
MySQL表級鎖的鎖模式
MyISAM在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,
在執行更新操作(DML)前,會自動給涉及的表加寫鎖。
所以對MyISAM表進行操作,會有以下情況:
a、對MyISAM表的讀操作(加讀鎖),不會阻塞其他進程(會話)對同一表的讀請求,
但會阻塞對同一表的寫請求。只有當讀鎖釋放后,才會執行其它進程的寫操作。
b、對MyISAM表的寫操作(加寫鎖),會阻塞其他進程(會話)對同一表的讀和寫操作,
只有當寫鎖釋放后,才會執行其它進程的讀寫操作。