mysql中InnoDB存儲引擎的行鎖和表鎖

Mysql的InnoDB存儲引擎支持事務,默認是行鎖。由於這個特性,因此數據庫支持高併發,可是若是InnoDB更新數據的時候不是行鎖,而是表鎖的話,那麼其併發性會大打折扣,並且也可能致使你的程序出錯。sql

而致使行鎖變爲表鎖的狀況之一就是:數據庫

  SQL的更新(update)或者刪除(delete)語句中未使用到索引,致使在InnoDB在對數據進行相應操做的時候必須把整個表鎖起來進行檢索(表鎖)。而若是使用了索引的話,InnoDB只會經過索引條件檢索數據,而只鎖住索引對應的行(行鎖)。併發

下面記錄一下我遇到的問題:高併發

  描述:測試

  1. 系統中有一個實時的定時任務,當有條件觸發的時候,會更新對應的表,就先叫其爲A表;
  2. 可是同時有一個任務有時候會對A表有寫操做,所以當進行測試的時候,有時候會不固定的出「Lock wait timeout exceeded」的錯誤。

  當出現這個問題的時候,從不少的地方進行了分析,而後都沒法獲得正確的解決方案(由於描述1模塊不是我寫的,因此沒有去查看更新表的代碼操做)spa

  致使緣由:索引

       在描述1中定時任務更新表A的時候,更新條件中沒有使用索引,致使當進行定時任務更新表的時候造成了表鎖。而後由於表A數據量比較大,檢索較慢,而後致使了描述2中對錶A的寫操做的等鎖超時。事務

最多見的索引:it

  • 主鍵:衆所周知,自帶最高效的索引屬性
  • 惟一索引:屬性值重複率爲0,能夠做爲業務主鍵
  • 普通索引:屬性值重複率大於0,不能做爲惟一指定條件

  注意:對於普通索引,「重複率」低時,甚至接近主鍵或者惟一索引的效果時,依然是行鎖;可是若是「重複率」高時,Mysql不會把這個普通索引當作索引,即會形成一個沒有索引的SQL,從而造成表鎖。date

相關文章
相關標籤/搜索