`MySQL`的行鎖在引擎層由各個引擎自己實現的,但並不是所有的引擎都支持行鎖。 不支持行鎖意味著併發控制只能使用表鎖,對於這種引擎的表,同一張表任何時刻只能有一個更新在執行,這會影響到業務併發度。 引擎下的事務中,行鎖是需要的時候才加上的,但並不是不需要了立刻釋放,而是要等到事務結束時(commi ...
MySQL
的行鎖在引擎層由各個引擎自己實現的,但並不是所有的引擎都支持行鎖。
不支持行鎖意味著併發控制只能使用表鎖,對於這種引擎的表,同一張表任何時刻只能有一個更新在執行,這會影響到業務併發度。
InnoDB
引擎下的事務中,行鎖是需要的時候才加上的,但並不是不需要了立刻釋放,而是要等到事務結束時(commit時候)才釋放,成為兩階段鎖協議。
當併發系統中不同線程出現迴圈資源依賴,涉及的線程都在等待別的線程釋放資源時,就會導致這幾個線程都進入無限等待的狀態,稱為死鎖。
事務A在等待事務B釋放id=2的行鎖,事務B在等待事務釋放id=1的行鎖,相互等待對方釋放資源,就進入了死鎖的狀態。
出現了死鎖後,有兩種策略:
- 策略1,直接進入等待,直至超時。這個超時時間可以通過參數
innodb_lock_wait_timeout
來設置 - 策略2,發起死鎖檢測,發現死鎖後,主動回滾死鎖鏈條中的某一個事務,讓其他事務得以繼續執行。將參數
innodb_deadlock_detect
設置為on
,表示開啟這個邏輯
兩種策略都有優缺點,所以需要儘量避免死鎖。
如果一個事務中需要鎖多個行,要把最可能造成鎖衝突、最可能影響併發度的鎖的申請時機儘量往後放。