綜述
對MySQL中并發(fā)控制所用到的機(jī)制和鎖進(jìn)行整理。
- 行鎖
- 表鎖
- 間隙鎖
- 臨鍵鎖
- MVCC
- 悲觀鎖
- 樂觀鎖
行鎖 Record Locks
顧名思義,是針對數(shù)據(jù)中已經(jīng)存在的數(shù)據(jù)行上的鎖。
- 也叫
記錄鎖 - 在
InnoDB中,對索引列的操作會使用行鎖,非索引列的操作會使用表鎖(因為不在索引中,所以需要全表掃描) - 使用
<、>、!=等符號進(jìn)行范圍內(nèi)的查詢時,會加上行鎖和間隙鎖
表鎖 Table Locks
對整張數(shù)據(jù)表上的鎖。
對效率影響較大
-
代碼:
LOCK TABLES myTable WRITE; UNLOCK TABLES;
間隙鎖 Gap Locks
主要用于封鎖索引記錄間的間隔。
- 產(chǎn)生條件:
- 對不存在的記錄加鎖
- 范圍查詢
臨鍵鎖 Next-key Locks
就是行鎖和間隙鎖的組合。
- 封鎖范圍:索引記錄和索引區(qū)間
- 主要目的:避免幻讀
多版本并發(fā)控制 MVCC
每個事務(wù)的讀取操作所讀取到的都是數(shù)據(jù)在某個時刻的快照。
- 用于解決讀-寫沖突
悲觀鎖
每次操作都假設(shè)為最壞的情況:其他事務(wù)會對本事務(wù)用到的數(shù)據(jù)進(jìn)行操作。所以在事務(wù)開始時就直接對數(shù)據(jù)上鎖。
- 在查詢時就會鎖上數(shù)據(jù),直到數(shù)據(jù)被提交或者回滾
- 主要語法
FOR UPDATE:select * from myTable for update; 其他操作…… commit;
樂觀鎖
每次操作都假設(shè)其他事務(wù)不會使用本事務(wù)的數(shù)據(jù),所以只有在進(jìn)行寫操作的時候,才上鎖。
- 通過類似“版本號”的機(jī)制來實現(xiàn),讀的時候確定版本,寫的時候檢查版本號:
update myTable set (……,version) values (……, version + 1) where version = 1;