1. 表鎖
表鎖分爲寫鎖,讀鎖,兩者讀讀不阻塞,讀寫阻塞,寫寫阻塞mysql
2. 行鎖
行鎖分爲共享鎖,排他鎖,即讀鎖和寫鎖sql
多粒度鎖機制自動實現表、行鎖共存,InnoDB內部有意向表鎖數據庫
- 意向共享鎖(IS):事務在給一個數據行加共享鎖前必須先取得該表的IS鎖。
- 意向排他鎖(IX):事務在給一個數據行加排他鎖前必須先取得該表的IX鎖。
3. 表、行鎖區別
表鎖:開銷小,加鎖快;不會出現死鎖;鎖定力度大,發生鎖衝突機率高,併發度最低併發
行鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度小,發生鎖衝突的機率低,併發度高mvc
- InnoDB會自動給UPDATE、DELETE、INSERT加排他鎖(X)
- InnoDB查找時,只有用到了索引才加行鎖,不然加表鎖
- MyISAM會自動給SELECT加讀鎖,自動給UPDATE、DELETE、INSERT加寫鎖
- MyISAM查詢和插入能夠併發,若表中沒有被刪除的行,可在一個進程讀表的同時,另外一個進程從表尾插入數據,InnoDB不行
- mysql中同時加鎖,寫鎖優先於讀鎖
4. MVCC
鎖的應用最終致使不一樣事務的隔離級別、而MVCC多版本併發控制,經過增長版本的形式實現兩種隔離級別(不使用到鎖),MVCC讀寫不阻塞,是行級鎖的升級spa
隔離分爲語句級Readcommitted隔離級別和事務級Repeatableread隔離級別.net
語句級:設計
事務A讀取數據生成版本號code
事務B修改數據(加了寫鎖)索引
事務A再讀取數據時,是讀取最新版本號的(若事務B提交了生成新版本號,沒有提交則仍是原來的版本號)
這裏出現了不可重複讀,事務A數據根據事務B而改變
事務級:
事務A讀取數據生成版本號1
事務B修改數據生成新版本2
事務A再讀取數據仍是用版本號1
避免了不可重複讀,出現了幻讀
MySQL的 Repeatableread隔離級別加上GAP間隙鎖解決了幻讀,不須要串行了
5. 樂觀鎖和悲觀鎖
丟失更新:一個事務的更新覆蓋了其它事務的更新結果的解決方法:
- 使用Serializable隔離級別,事務是串行執行的,併發低
- 樂觀鎖
- 悲觀鎖
樂觀鎖:要在表中設計一個版本字段。第一次要獲取這個字段,處理完業務邏輯開始更新時,要對比如今的版本字段和第一次的版本字段是否相同,相同則更新反之拒絕。這裏沒有給數據庫加鎖,須要咱們手動操做
UPDATE <表名> SET name="Howl",version=version+1 WHERE ID=#{id} AND version=#{version}
悲觀鎖:是數據庫層面加鎖,至關於排他鎖,其餘的事務就不能對它修改了,須要等待當前事務修改完以後才能夠修改,在 select 語句後面加 FOR UPDATE
# 須要在事務中加,由於select是不加任何行鎖的 SELECT * FROM <表名> FOR UPDATE / LOCK IN SHARE MODE
6. 間隙鎖GAP
在範圍查找時若請求寫鎖或讀鎖,InnoDB會給符合範圍條件的已有數據的索引項加鎖
對於鍵值在條件範圍內但並不存在的記錄,叫作間隙
間隙鎖只會在Repeatableread及如下隔離級別使用,做用於防止幻讀
本文分享 CNBlog - Howlet。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。