(Mysql 七)InnoDB引擎的行鎖和表鎖
mysql常用引擎有MYISAM和InnoDB,而InnoDB是mysql預設的引擎。MYISAM不支援行鎖,而InnoDB支援行鎖和表鎖。
1.行鎖和表鎖
2.行鎖的型別
3.行鎖的實現
1.行鎖和表鎖
在mysql 的 InnoDB引擎支援行鎖,與Oracle不同,mysql的行鎖是通過索引載入的,即是行鎖是加在索引響應的行上的,要是對應的SQL語句沒有走索引,則會全表掃描,
行鎖則無法實現,取而代之的是表鎖。
表鎖:不會出現死鎖,發生鎖衝突機率高,併發低。
行鎖:會出現死鎖,發生鎖衝突機率低,併發高。
鎖衝突:例如說事務A將某幾行上鎖後,事務B又對其上鎖,鎖不能共存否則會出現鎖衝突。(但是共享鎖可以共存,共享鎖和排它鎖不能共存,排它鎖和排他鎖也不可以)
死鎖:例如說兩個事務,事務A鎖住了1~5行,同時事務B鎖住了6~10行,此時事務A請求鎖住6~10行,就會阻塞直到事務B施放6~10行的鎖,而隨後事務B又請求鎖住1~5行,事務B也阻塞直到事務A釋放1~5行的鎖。死鎖發生時,會產生Deadlock錯誤。
鎖是對錶操作的,所以自然鎖住全表的表鎖就不會出現死鎖。
2.行鎖的型別
行鎖分 共享鎖 和 排它鎖。
共享鎖又稱:讀鎖。當一個事務對某幾行上讀鎖時,允許其他事務對這幾行進行讀操作,但不允許其進行寫操作,也不允許其他事務給這幾行上排它鎖,但允許上讀鎖。
排它鎖又稱:寫鎖。當一個事務對某幾個上寫鎖時,不允許其他事務寫,但允許讀。更不允許其他事務給這幾行上任何鎖。包括寫鎖。
上共享鎖的寫法:lock in share mode
例如: select math from zje where math>60 lock in share mode;
上排它鎖的寫法:for update
例如:select math from zje where math >60 for update;
3.行鎖的實現
注意幾點:
1.行鎖必須有索引才能實現,否則會自動鎖全表,那麼就不是行鎖了。
2.兩個事務不能鎖同一個索引,例如:
3.insert ,delete , update在事務中都會自動預設加上排它鎖。事務A先執行: select math from zje where math>60 for update; 事務B再執行: select math from zje where math<60 for update; 這樣的話,事務B是會阻塞的。如果事務B把 math索引換成其他索引就不會阻塞,但注意,換成其他索引鎖住的行不能和math索引鎖住的行有重複。
實現:
會話1: begin; select math from zje where math>60 for update; |
會話2: begin; update zje set math=99 where math=68; 阻塞........... |
如上,會話1先把zje表中math>60的行上排它鎖。然後會話2試圖把math=68的行進行修改,math=68處於math>60中,所以是已經被鎖的,會話2進行操作時,
就會阻塞,等待會話1把鎖釋放。當commit時或者程式結束時,會釋放鎖。