官方定義以下:兩個事務都持有對方須要的鎖,而且在等待對方釋放,而且雙方都不會釋放本身的鎖。mysql
這個就比如你有一我的質,對方有一我的質,大家倆去談判說換人。你讓對面放人,對面讓你放人。sql
看到這裏,也許你會有這樣的疑問,事務和談判不同,爲何事務不能使用完鎖以後立馬釋放呢?竟然還要操做完了以後一直持有鎖?這就涉及到 MySQL 的併發控制了。併發
MySQL的併發控制有兩種方式,一個是 MVCC,一個是兩階段鎖協議。那麼爲何要併發控制呢?是由於多個用戶同時操做 MySQL 的時候,爲了提升併發性能而且要求如同多個用戶的請求過來以後如同串行執行的同樣(可串行化調度
)。具體的併發控制這裏再也不展開。我們繼續深刻討論兩階段鎖協議。高併發
官方定義:性能
兩階段鎖協議是指全部事務必須分兩個階段對數據加鎖和解鎖,在對任何數據進行讀、寫操做以前,事務首先要得到對該數據的封鎖;在釋放一個封鎖以後,事務再也不申請和得到任何其餘封鎖。.net
對應到 MySQL 上分爲兩個階段:命令行
就是說呢,只有遵循兩段鎖協議,才能實現 可串行化調度
。調試
可是兩階段鎖協議不要求事務必須一次將全部須要使用的數據加鎖,而且在加鎖階段沒有順序要求,因此這種併發控制方式會造成死鎖。日誌
MySQL有兩種死鎖處理方式:code
因爲性能緣由,通常都是使用死鎖檢測來進行處理死鎖。
死鎖檢測的原理是構建一個以事務爲頂點、鎖爲邊的有向圖,判斷有向圖是否存在環,存在即有死鎖。
檢測到死鎖以後,選擇插入更新或者刪除的行數最少的事務回滾,基於 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段來判斷。
SHOW ENGINE INNODB STATUS
查看死鎖緣由。lock tables
。(SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE)
,嘗試下降隔離級別。將修改的順序保持一致
。(SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE)
。lock tables t1, t2, t3
鎖多張表