mysql-【鎖】總結

讀鎖與寫鎖

X鎖 S鎖
X鎖 衝突 衝突
S鎖 衝突 不衝突

讀鎖:當前事務給某些數據加了讀鎖,容許其餘事務加讀鎖但不容許加寫鎖。也能夠稱之爲共享鎖、Shared Locks、S鎖

示例

select * from table_a lock in share modemysql

使用場景:讀出數據後其餘事務不能修改,但本身也不必定能修改,由於其餘事務也能夠加讀鎖。主要用來保證數據在本事務內值不會變。但實際開發中用得比較少。sql

寫鎖:當前事務若是加了寫鎖,其餘事務若加鎖會阻塞。也能夠稱之爲排他鎖、Exclusice Locks、X鎖

示例

select * from table_a for update 以及 DELETE/UPDATE/INSERT(插入後未提交的數據也會加寫鎖)性能

使用場景:只有本事務才能夠修改這些數據,其餘事務加鎖會阻塞。通常開發過程當中大部分接觸到的鎖都是寫鎖。索引

行鎖與表鎖

行鎖:只有InnoDB裏纔會有。

行鎖又分爲:事務

  • LOCK_REC_NOT_GAP:單個行記錄上的鎖。
  • LOCK_GAP:間隙鎖,鎖定一個範圍,但不包括記錄自己。什麼意思呢?好比查詢一條ID爲7的數據,間隙鎖是給ID=7這條數據上下記錄間的間隙給鎖定,但記錄自己不上鎖。就如MVCC是解決可重複讀的問題同樣,間隙鎖是解決幻讀的問題,即同一事務內,數據總數不變。
  • LOCK_ORDINARY:同上,也是間隙鎖,只是鎖定範圍包括記錄自己。咱們通常所說的間隙鎖就是這個。

示例:

select * from table_a where a = 1 for update開發

  • 事務隔離級別爲讀提交時 會對查詢出的全部每條數據加行鎖(單個行記錄上鎖),但此時其餘事務能夠針對這個數據範圍insert形成幻讀。table

  • 當事務隔離級別爲可重複讀時(mysql默認的事務隔離級別) 若是走索引,mysql經過索引知道數據的範圍,會對查詢出的數據範圍間隙及數據自己加鎖,其餘事務針對這個數據範圍寫操做都會阻塞,包括insert在這個間隙範圍內的操做,以免幻讀。class

但若是sql語句不走索引全表掃描,此時mysql並不知道數據範圍,mysql只能對全部的數據和間隙上鎖以免幻讀。date

表鎖

表鎖在InnoDB中應用不多,寫操做是不會加表級別的鎖。select

而DDL語句也會發生阻塞,這個過程是經過使用元數據鎖(Metadata Locks,MDL)來實現的,並非表級別的鎖。 可是能夠用過如下方式加表鎖

  • LOCK TABLES t1 READ
  • LOCK TABLES t1 WRITE

可是不建議使用,由於InnoDB的優勢就是行鎖,表鎖性能差。

總結

  • mysql默認事務隔離級別是可重複讀,因此須要重點關注的概念:寫鎖、行鎖、間隙鎖。
  • 讀鎖與寫鎖是對鎖功能的分類,而行鎖與表鎖是對鎖範圍的一個分類。
相關文章
相關標籤/搜索