mysql雜說——mysql鎖

  Mysql用到了不少這種鎖機制,行鎖,表鎖等,讀鎖,寫鎖等,都是在作操做以前先上鎖。這些鎖統稱爲悲觀鎖(Pessimistic Lock)。html

一、mysql存儲引擎分爲:innodb 和 myisammysql

                 事務,             表鎖            行鎖 sql

innodb      支持                 支持            支持      數據庫

myisam     不支持     支持    不支持併發

二、數據庫鎖:行鎖的是索引spa

      加鎖的目的:減小資源的競爭設計

表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的機率最高,併發度最低。 
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,併發度也最高。 
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度通常 htm

 

三、對象

 

 

 mysql5.7解決了幻讀:解決思路經過間隙鎖防止幻讀,以知足相關隔離級別的要求blog

間隙鎖:1,3,5           存在(-∞,1),(1,3),(3,5),(5,∞) 四個間隙,分別存在4個間隙鎖

四、InnoDB實現瞭如下兩種類型的行鎖。

  • 共享鎖(s):又稱讀鎖。容許一個事務去讀一行,阻止其餘事務得到相同數據集的排他鎖。若事務T對數據對象A加上S鎖,則事務T能夠讀A但不能修改A,其餘事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這保證了其餘事務能夠讀A但在T釋放A上的S鎖以前不能對A作任何修改
  • 排他鎖(X):又稱寫鎖。容許獲取排他鎖的事務更新數據,阻止其餘事務取得相同的數據集共享讀鎖和排他寫鎖。若事務T對數據對象A加上X鎖,事務T能夠讀A也能夠修改A,其餘事務不能再對A加任何鎖,直到T釋放A上的鎖。

對於共享鎖你們可能很好理解,就是多個事務只能讀數據不能改數據。 
對於排他鎖你們的理解可能就有些差異,我當初就犯了一個錯誤,覺得排他鎖鎖住一行數據後,其餘事務就不能讀取和修改該行數據,其實不是這樣的。排他鎖指的是一個事務在一行數據加上排他鎖後,其餘事務不能再在其上加其餘的鎖。mysql InnoDB引擎默認的修改數據語句:update,delete,insert都會自動給涉及到的數據加上排他鎖,select語句默認不會加任何鎖類型,若是加排他鎖可使用select …for update語句,加共享鎖可使用select … lock in share mode語句。因此加過排他鎖的數據行在其餘事務種是不能修改數據的,也不能經過for update和lock in share mode鎖的方式查詢數據,但能夠直接經過select …from…查詢數據,由於普通查詢沒有任何鎖機制。

五、爲了容許行鎖和表鎖共存,實現多粒度鎖機制,InnoDB還有兩種內部使用的意向鎖(Intention Locks)兩種意向鎖都是表鎖

  • 意向共享鎖(IS):事務打算給數據行共享鎖,事務在給一個數據行加共享鎖前必須先取得該表的IS鎖。
  • 意向排他鎖(IX):事務打算給數據行加排他鎖,事務在給一個數據行加排他鎖前必須先取得該表的IX鎖。

我的總結:意向共享鎖(IS)和意向排他鎖(IX)就是一個標誌。在加共享鎖(s)和排他鎖(X)以前看看數據庫有沒有意向鎖,目的:提升數據庫加鎖效率。

六、InnoDB行鎖模式兼容性列表: 

 

 

 7:InnoDB行鎖是經過給索引上的索引項加鎖來實現的,InnoDB這種行鎖實現特色意味着:只有經過索引條件檢索數據,InnoDB才使用行級鎖,不然,InnoDB將使用表鎖! 

注意:因爲MySQL的行鎖是針對索引加的鎖,不是針對記錄加的鎖,因此雖然是訪問不一樣行的記錄,可是若是是使用相同的索引鍵,是會出現鎖衝突的

八、幾種概念:

間隙鎖:當咱們用範圍條件而不是相等條件檢索數據,並請求共享或排他鎖時,InnoDB會給符合條件的已有數據記錄的 索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫作「間隙(GAP)」,InnoDB也會對這個「間隙」加鎖。

 

小結:

 

對於InnoDB表,本文主要討論瞭如下幾項內容: 
(1)InnoDB的行鎖是基於索引實現的,若是不經過索引訪問數據,InnoDB會使用表鎖。 
(2)介紹了InnoDB間隙鎖(Next-key)機制,以及InnoDB使用間隙鎖的緣由。 
在不一樣的隔離級別下,InnoDB的鎖機制和一致性讀策略不一樣。

 

在瞭解InnoDB鎖特性後,用戶能夠經過設計和SQL調整等措施減小鎖衝突和死鎖,包括:

 

  • 儘可能使用較低的隔離級別; 精心設計索引,並儘可能使用索引訪問數據,使加鎖更精確,從而減小鎖衝突的機會;
  • 選擇合理的事務大小,小事務發生鎖衝突的概率也更小;
  • 給記錄集顯式加鎖時,最好一次性請求足夠級別的鎖。好比要修改數據的話,最好直接申請排他鎖,而不是先申請共享鎖,修改時再請求排他鎖,這樣容易產生死鎖;
  • 不一樣的程序訪問一組表時,應儘可能約定以相同的順序訪問各表,對一個表而言,儘量以固定的順序存取表中的行。這樣能夠大大減小死鎖的機會;
  • 儘可能用相等條件訪問數據,這樣能夠避免間隙鎖對併發插入的影響; 不要申請超過實際須要的鎖級別;除非必須,查詢時不要顯示加鎖;
  • 對於一些特定的事務,可使用表鎖來提升處理速度或減小死鎖的可能。

 

博客原文:http://www.javashuo.com/article/p-fqrzmnlo-kv.html

相關文章
相關標籤/搜索