MySQL死鎖分析

熟悉或者瞭解數據庫的朋友都知道鎖的概念,這裏不做過多的解析!鎖的種類有很多,不同數據庫的鎖管理方式也不同。這裏主要談下MySQL innodb引擎下的死鎖。


死鎖通俗的來講就是2個事務相互請求對方持有的鎖,這樣就會造成2個事務相互等待對方釋放的鎖資源,於是這就是死鎖。

事務A事務B
begin;

select * from t where a = 1 for update;begin;

select * from t where a = 2 for update;

select * from t where a = 2 for update;
#等待



select * from t where a = 1 for update;

#ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

首先INNODB引擎不會回滾大多數的異常,但死鎖除外。再發現死鎖後,Innodb會立即回滾其中一個事務(這裏回滾依據,會設計到權重問題)。例子中事務B被回滾!這是最常見的一種死鎖例子。


MySQL還有另外一種死鎖情況:當前事務持有待插入記錄的下一個記錄的X鎖(排他鎖),但此時等待的隊列中存在一個S鎖的請求,則可能會發生死鎖。首先創建一個測試用的表,並插入數據:

create table test( a int primary key) engine=innodb;

insert into test values (1),(2),(4),(5);

時間事務A事務B
1begin;
2
begin;
3

select * from test where

 a = 4 for update;


4

select * from test where

a<=4 lock in share mode;

#等待

5

insert into test values (3)

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction


6
#事務獲得鎖,正常運行

事務A中已經對記錄4持有了X鎖,但會話A插入記錄3的時候會導致死鎖發生。這個問題產生是由於事務B中請求記錄4的S鎖而發生等待,但之前請求鎖對於主鍵記錄1、2都已經成功,若再時間5能插入記錄,那麼事務B在獲取記錄4持有的S鎖後,還需要向後獲得記錄3的記錄,這顯得不合理。於是INNODB引擎在這裏主動選擇死鎖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章