免費(fèi)空間申請(qǐng)網(wǎng)站google關(guān)鍵詞搜索技巧
InnoDB通過MVCC+Next-Key Locks,解決了可重復(fù)讀的事務(wù)隔離級(jí)別出現(xiàn)的幻讀問題。
記錄鎖
記錄鎖就是為某行數(shù)據(jù)進(jìn)行加鎖,它封鎖該行的索引記錄
SELECT * FROM table WHERE id = 1 FOR UPDATE
id為1的記錄行會(huì)被鎖住。需要注意的的:id列必須為唯一索引列或主鍵列,否者上屬于語句加鎖就會(huì)變成臨建鎖。同時(shí),查詢語句必須是精準(zhǔn)匹配(=),不能是>,<,like等,否者會(huì)退化為臨建鎖
執(zhí)行Update操作也會(huì)加上記錄鎖
UPDATE table SET age = 20 WHERE id = 1
間隙鎖
間隙鎖是基于非唯一索引,它鎖定的是一段范圍內(nèi)的索引記錄,間隙鎖鎖住的是有一個(gè)區(qū)間,而不僅僅是這個(gè)區(qū)間中的每一條數(shù)據(jù)
SELECT * FROM table WHERE i BETWEEN 1 AND 10 FOR UPDATE
即所有在(1,10)區(qū)間的記錄都會(huì)鎖住,所有id 為 2、3、4、5、6、7、8、9 的數(shù)據(jù)行的插入會(huì)被阻塞,但是 1 和 10 兩條記錄行并不會(huì)被鎖住
臨鍵鎖
臨鍵鎖可以理解為一種特殊的間隙鎖。通過臨鍵鎖可以解決幻讀問題,每個(gè)數(shù)據(jù)行上的非唯一索引列都會(huì)存在一把臨鍵鎖,當(dāng)某個(gè)事務(wù)持有該數(shù)據(jù)行的臨鍵鎖時(shí),會(huì)所主要有一段左開右閉區(qū)間的數(shù)據(jù),需要強(qiáng)調(diào)的一點(diǎn)是,InnoDB中的行級(jí)鎖是基于索引實(shí)現(xiàn)的,臨鍵鎖只與非唯一索引有關(guān),在唯一索引中不存在臨鍵鎖。
假設(shè)有如下表:
MySql,InnoDB,Repeatable-Read:table(id PK, age KEY, name)
id | age | name |
1 | 10 | Lee |
3 | 24 | Soraka |
5 | 32 | Zed |
7 | 45 | Talon |
該表中 age
列潛在的臨鍵鎖
有:
(-∞, 10],
(10, 24],
(24, 32],
(32, 45],
(45, +∞],
在事務(wù) A
中執(zhí)行如下命令:
UPDATE table SET name = Vladimir WHERE age = 24
或:
SELECT * FROM table WHERE age = 24 FOR UPDATE
之后事務(wù)B執(zhí)行以下命令,則該命令會(huì)被阻塞等待:
INSERT INTO table VALUES(100, 26, 'Ezreal')
事務(wù)A在對(duì)age為24的列進(jìn)行UPDATE操作的同時(shí),也獲取了(24,32]這個(gè)區(qū)間的臨鍵鎖
總結(jié)
- InnoDB中的行鎖的實(shí)現(xiàn)依賴于索引,一旦某個(gè)加鎖的操作沒有用到索引就會(huì)退化到表鎖
- 記錄鎖存在在于包括主鍵索引在內(nèi)的唯一索引,鎖定單條索引記錄
- 間隙鎖存在于非唯一索引,鎖定開區(qū)間的一段間隔,它是基于臨鍵鎖實(shí)現(xiàn)的
- 臨鍵鎖存在于非唯一索引,該類型每條記錄的索引都會(huì)存在這個(gè)鎖,鎖定一段左開右閉的索引區(qū)間