Mysql鎖



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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索