mysql行鎖 死鎖 mysql行鎖和死鎖檢測

2021-10-17 13:52:13 字數 1476 閱讀 1601

行鎖顧名思義,就是針對單行資料加鎖,在mysql中,鎖的實現是由引擎層實現的,myisam引擎就不支援行鎖

不支援行鎖就意味著併發控制只能使用表鎖,也就是說同一時間,在這個表上只能有乙個更新在執行,這就會

影響到業務的併發度。innodb是支援行鎖的,這也是myisam被innodb替代的重要原因之一。

兩階段鎖協議

先舉個例子,事務b的語句執行的時候會發生什麼現象?這取決於事務a在執行完兩條語句後持有那些鎖,以及在什麼時候釋放?

大家可以自己做個實驗,是這樣的,事務b在執行這條語句時會被阻塞,大家會不會有疑惑,

前面兩條語句不是執行完了嗎?

為什麼還會阻塞?

其實事務a的加鎖時機是執行第一條語句的時候,釋放鎖的時候是commit完以後

但是事務b是在事務a commit前執行的

這個時候事務a還持有id=1這行資料的鎖,所以事務b會被阻塞。

知道了這個原理對於我們有什麼啟示呢?

既然知道了鎖的釋放是在commit之後

那麼我們就可以把最可能造成鎖衝突

最可能影響併發度的鎖盡量往後放

舉個例子:

業務:顧客a要在影院b買一張電影票

操作:1.從顧客a的賬戶餘額中減掉電影票的**

2.將影院b的賬戶餘額增加這張電影票價

3.增加一條操作日誌

大家想想看,這三個操作,那個最容易影響到併發度會造成鎖衝突

很明顯是第二個操作,為啥呢?想想看操作1中只是鎖了這個使用者的

這行資料,只對他自己有影響,這個時候如果有個顧客c也買了電影

票,那麼這個時候的衝突就是操作2了,因為人家也需要更新影院的

賬戶餘額,所以我們要把操作2放在最後執行,因為這樣對操作2涉及的

行鎖,鎖住時間就會少一點,最大程度的減少了事務之間的等待

提公升了併發度。

死鎖和死鎖檢測

如圖所示,事務a在等待事務b釋放id=2的鎖,事務b在等待事務a釋放id=1的鎖

這種情況就是死鎖

發生死鎖有兩種方法解決

1.直接進入等待,直到超時。這個超時時間可以通過引數innodb_lock_wait_timeout來設定

2.發起死鎖檢測,發現死鎖後,主動回滾死鎖鏈條中的某乙個事務,讓其他事務得以執行。

將引數innodb_deadlock_detect設定為on,表示開啟這個邏輯

在innodb中,innodb_lock_wait_timeout的值預設是50s,以為著如果使用第一種方法,

第乙個被鎖住的執行緒要過50s才會超時退出,然後其他執行緒才有可能繼續執行。

但是我們又不能把這個時間設定的很小,比如1s,如果這個時候不是死鎖,而是正常的鎖等待呢

這樣就會造成很多誤傷,所以我們還是使用死鎖檢測好一些,好在innodb_deadlock_detect預設就是on

其實死鎖檢測也是會占用很多cpu資源的,當事務被鎖住的時候,就要看看它鎖依賴的執行緒有沒有被別人鎖住

如此迴圈,最後判斷是否出現了迴圈等待,也就是死鎖

mysql 行鎖 訂票 mysql 行鎖

在電子商務裡,經常會出現庫存數量少,購買的人又特別多,大併發情況下如何確保商品數量不會被多次購買.其實很簡單,利用事務 for update就可以解決.我們都知道for update實際上是共享鎖,是可以被讀取的.但是如何在執行時,不被讀取呢.簡單來說 假設現在庫存為1,現在有a和b同時購買 先開啟...

mysql行鎖詳解 詳解MySQL行鎖

鎖是計算機協調多個程序或執行緒併發訪問某一資源的機制。鎖保證資料併發訪問的一致性 有效性 鎖衝突也是影響資料庫併發訪問效能的乙個重要因素。鎖是mysql在伺服器層和儲存引擎層的的併發控制。mysql中從對資料操作的粒度分為表鎖和行鎖。表鎖是指對一整張表加鎖,一般是 ddl 處理時使用 而行鎖則是鎖定...

mysql行鎖的特性 MySql的表鎖行鎖及間隙鎖

常用命令 手動新增表鎖 lock table 表名稱 read write 表名稱2 read write 檢視表上加過的鎖 show open tables 刪除表鎖 unlock tables 1.表鎖 特點 1.每次操作鎖住整張表,開銷小,加鎖快 2.不會出現死鎖 3.鎖定粒度大,發生鎖衝突的...