InnoDB行鎖,如何鎖住一條不存在的記錄?
《InnoDB,5項***實踐,知其所以然?》發(fā)布后,不少同學(xué)留言希望講講MySQL的InnoDB行鎖機制。要細聊MySQL的行鎖,難以避免的要從事務(wù)的四種隔離級別說起。
四種隔離級別,又脫不開聊讀臟,不可重復(fù)讀,讀幻象等問題。
事務(wù)隔離級別,行鎖機制等都比較垂直,應(yīng)用開發(fā)中大部分同學(xué)都用不到,不確定是否大部分朋友都感興趣。
今天,先拋出一個問題,如果大家確定對這類話題感興趣的話,后續(xù)我花時間細聊這一系列問題。
MySQL默認的事務(wù)隔離級別是 Repeated Read (RR),假設(shè)使用的存儲引擎是InnoDB,在這個隔離級別下:
- 讀取到數(shù)據(jù),都是其他事務(wù)已提交的數(shù)據(jù);
- 同一個事務(wù)中,相同的連續(xù)讀,得到的結(jié)果應(yīng)該是相同的;
- 不會出現(xiàn)insert幻象讀;
假設(shè)有數(shù)據(jù)表:
- t(id int PK, name)
假設(shè)目前的記錄是:
- 10, shenjian
- 20, zhangsan
- 30, lisi
Case 1
事務(wù)A先執(zhí)行,并且處于未提交狀態(tài):
- update t set name=’a’ where id=10
事務(wù)B后執(zhí)行:
- update t set name=’b’ where id=10
因為事務(wù)A在PK id=10上加了行鎖,因此事務(wù)B會阻塞。
Case 2
事務(wù)A先執(zhí)行,并且處于未提交狀態(tài):
- delete from t where id=40
事務(wù)A想要刪除一條不存在的記錄。
事務(wù)B后執(zhí)行:
- insert into t values(40, ‘c’)
事務(wù)B想要插入一條主鍵不沖突的記錄。
- 問題1:事務(wù)B是否阻塞?
- 問題2:如果事務(wù)B阻塞,鎖如何加在一條不存在的記錄上呢?
- 問題3:事務(wù)的隔離級別,索引類型,是否對問題1和問題2有影響呢?
如果大家對這些問題感興趣,后續(xù)我花時間深入梳理邏輯,畫圖細聊。
如果不感興趣,我換數(shù)據(jù)庫應(yīng)用層架構(gòu)的話題。
是不是很有意思的一個問題?
猜猜InnoDB的行鎖是怎么做到的?
【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】