IS | IX | |
IS | 兼 容 | 兼 容 |
IX | 兼 容 | 兼 容 |
雖然意向鎖之間互相兼容,但是它與共享鎖/排它鎖互斥,其兼容互斥表如下:
S | X | |
IS | 兼 容 | 互 斥 |
IX | 互 斥 | 互 斥 |
排它鎖是很強(qiáng)的鎖,不與其他類型的鎖兼容。這其實(shí)很好理解,修改和刪除某一行的時(shí)候,必須獲得強(qiáng)鎖,禁止這一行上的其他并發(fā),以保障數(shù)據(jù)的一致性。
3. 記錄鎖(Record Locks)
記錄鎖,它封鎖索引記錄,例如(其中id為pk):
create table lock_example(id smallint(10),name varchar(20),primary key id)engine=innodb;
數(shù)據(jù)庫隔離級別為RR,表中有如下數(shù)據(jù):
10, zhangsan
20, lisi
30, wangwu
select * from t where id=1 for update;
其實(shí)這里是先獲取該表的意向排他鎖(IX),再獲取這行記錄的排他鎖(我的理解是因?yàn)檫@里直接命中索引了),以阻止其他事務(wù)插入,更新,刪除id=1的這一行。
4. 間隙鎖(Gap Locks)
間隙鎖,它封鎖索引記錄中的間隔,或者第一條索引記錄之前的范圍,又或者最后一條索引記錄之后的范圍。依然是上面的例子,InnoDB,RR:
select * from lock_example where id between 8 and 15 for update;
這個(gè)SQL語句會封鎖區(qū)間(8,15),以阻止其他事務(wù)插入id位于該區(qū)間的記錄。
間隙鎖的主要目的,就是為了防止其他事務(wù)在間隔中插入數(shù)據(jù),以導(dǎo)致“不可重復(fù)讀”。如果把事務(wù)的隔離級別降級為讀提交(Read Committed, RC),間隙鎖則會自動失效。
5. 臨鍵鎖(Next-key Locks)
臨鍵鎖,是記錄鎖與間隙鎖的組合,它的封鎖范圍,既包含索引記錄,又包含索引區(qū)間。
默認(rèn)情況下,innodb使用next-key locks來鎖定記錄。但當(dāng)查詢的索引含有唯一屬性的時(shí)候,Next-Key Lock 會進(jìn)行優(yōu)化,將其降級為Record Lock,即僅鎖住索引本身,不是范圍。
舉個(gè)例子,依然是如上的表lock_example,但是id降級為普通索引(key),也就是說即使這里聲明了要加鎖(for update),而且命中的是索引,但是因?yàn)樗饕谶@里沒有UK約束,所以innodb會使用next-key locks,數(shù)據(jù)庫隔離級別RR:
事務(wù)A執(zhí)行如下語句,未提交:
select * from lock_example where id = 20 for update;
事務(wù)B開始,執(zhí)行如下語句,會阻塞:
insert into lock_example values('zhang',15);
如上的例子,事務(wù)A執(zhí)行查詢語句之后,默認(rèn)給id=20這條記錄加上了next-key lock,所以事務(wù)B插入10(包括)到30(不包括)之間的記錄都會阻塞。臨鍵鎖的主要目的,也是為了避免幻讀(Phantom Read)。如果把事務(wù)的隔離級別降級為RC,臨鍵鎖則也會失效。
6. 插入意向鎖(Insert Intention Locks)
對已有數(shù)據(jù)行的修改與刪除,必須加強(qiáng)互斥鎖(X鎖),那么對于數(shù)據(jù)的插入,是否還需要加這么強(qiáng)的鎖,來實(shí)施互斥呢?插入意向鎖,孕育而生。
插入意向鎖,是間隙鎖(Gap Locks)的一種(所以,也是實(shí)施在索引上的),它是專門針對insert操作的。多個(gè)事務(wù),在同一個(gè)索引,同一個(gè)范圍區(qū)間插入記錄時(shí),如果插入的位置不沖突,不會阻塞彼此。
Insert Intention Lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap.
舉個(gè)例子(表依然是如上的例子lock_example,數(shù)據(jù)依然是如上),事務(wù)A先執(zhí)行,在10與20兩條記錄中插入了一行,還未提交:
insert into t values(11, xxx);
事務(wù)B后執(zhí)行,也在10與20兩條記錄中插入了一行:
insert into t values(12, ooo);
因?yàn)槭遣迦氩僮?,雖然是插入同一個(gè)區(qū)間,但是插入的記錄并不沖突,所以使用的是插入意向鎖,此處A事務(wù)并不會阻塞B事務(wù)。
7. 自增鎖(Auto-inc Locks)
自增鎖是一種特殊的表級別鎖(table-level lock),專門針對事務(wù)插入AUTO_INCREMENT類型的列。最簡單的情況,如果一個(gè)事務(wù)正在往表中插入記錄,所有其他事務(wù)的插入必須等待,以便第一個(gè)事務(wù)插入的行,是連續(xù)的主鍵值。
AUTO-INC lock is a special table-level lock taken by transactions inserting into tables with AUTO_INCREMENT columns. In the simplest case, if one transaction is inserting values into the table, any other transactions must wait to do their own inserts into that table, so that rows inserted by the first transaction receive consecutive primary key values.
舉個(gè)例子(表依然是如上的例子lock_example),但是id為AUTO_INCREMENT,數(shù)據(jù)庫表中數(shù)據(jù)為:
1, zhangsan
2, lisi
3, wangwu
事務(wù)A先執(zhí)行,還未提交: insert into t(name) values(xxx);
事務(wù)B后執(zhí)行: insert into t(name) values(ooo);
此時(shí)事務(wù)B插入操作會阻塞,直到事務(wù)A提交。
總結(jié)
以上總結(jié)的7種鎖,個(gè)人理解可以按兩種方式來區(qū)分:
1. 按鎖的互斥程度來劃分,可以分為共享、排他鎖;
2. 按鎖的粒度來劃分,可以分為:
其中
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
標(biāo)簽:黃山 蘭州 佛山 南充 賀州 黔南 馬鞍山 宿遷
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《mysql中的鎖機(jī)制深入講解》,本文關(guān)鍵詞 mysql,中的,鎖,機(jī)制,深入,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。