行鎖
各個搜索引擎有自己的行鎖實現方式。MyIsam沒有實現行鎖,這個是被innodb取代在原因之一。
innodb實現行鎖基於索引,如果沒有使用索引,innodb將鎖住整個表。
兩段鎖協議:innodb不會在事務一開始就加行鎖,而是在執行到對應的腳本時,才進行加行鎖,並且在事務提交後才釋放鎖。
死鎖與檢測
由於資源的獨佔和循環等待釋放,而進入無限等待的階段。
解決:
方案1:設置innodb_lock_wait_timeout等待時間,等待超時就進行事務回滾。
方案2:發起死鎖校驗,innodb_deadlock_detect設置爲on。當發現死鎖時,進行事務回滾,以讓其他事務正常執行。
方案1如果設置時間過長,將不能讓程序接受,設置時間過斷,會誤傷部分正常的事務。
方案2比較推薦,但是死鎖校驗會有性能問題。比如有1000條事務進行死鎖校驗,那麼校驗的時間複雜度爲o(n),也就是100w級別的。這個過程會大量消耗cup,但是卻執行不了多少事務。優化方案:控制併發數,或者關閉死鎖校驗(危險)
思考題
如果你要刪除一個表裏面的前10000行數據,有以下三種方法可以做到:
- 第一種,直接執行delete from T limit 10000;
- 第二種,在一個連接中循環執行20次 delete from T limit 500;
- 第三種,在20個連接中同時執行delete from T limit 500。
答案:第二種方案
第一種方案事務時間太長,容易導致主從延遲,並且加鎖時間也比較長。
第二種比較適合,
第三種方案認爲製造衝突,除非加上特地過濾條件。