MySQL鎖機(jī)制
定義
數(shù)據(jù)庫(kù)鎖機(jī)制簡(jiǎn)單來說厘托,就是數(shù)據(jù)庫(kù)為了保證數(shù)據(jù)的一致性铅匹,使各種共享資源在被并發(fā)訪問時(shí)變得有序而設(shè)計(jì)一的一種規(guī)則饺藤。
表鎖與行鎖的比較
-
表鎖:鎖定整張表記錄
開銷小涕俗、加鎖快
不會(huì)出現(xiàn)死鎖
鎖粒度大再姑,發(fā)生鎖沖突的概率高,并發(fā)度相對(duì)低
-
行鎖:鎖定表中的一行或幾行記錄
開銷大绍填,加鎖慢
會(huì)出現(xiàn)死鎖
鎖粒度小栖疑,發(fā)生鎖沖突的概率低遇革,并發(fā)度也相對(duì)表鎖較高
InnoDB的鎖類型
InnoDB的行鎖類型主要有讀鎖(共享鎖)澳淑、寫鎖(排他鎖)、意向鎖和MDL鎖
-
讀鎖
定義:簡(jiǎn)稱 S 鎖量窘,一個(gè)事務(wù)獲取了一個(gè)數(shù)據(jù)行的讀鎖蚌铜,其他事務(wù)也能獲取該行對(duì)應(yīng)的讀鎖嫩海,但不能獲取寫鎖
讀鎖有兩種select方式的應(yīng)用:
自動(dòng)提交模式下的select叁怪,不需要加任何鎖,直接返回查詢結(jié)果
通過select……lock in share mode 在被讀取行記錄或行記錄的范圍上加一個(gè)讀鎖涣觉,讓其他事務(wù)可以讀官册,但時(shí)要想加寫鎖膝宁,那就會(huì)被阻塞
-
寫鎖
定義:簡(jiǎn)稱X鎖,一個(gè)事務(wù)獲取了一個(gè)數(shù)據(jù)行的寫鎖合蔽,其他事務(wù)就不能在獲取改行的其他鎖(寫鎖與讀鎖)辈末,寫鎖優(yōu)先級(jí)最高
寫鎖的應(yīng)用:
- select…… for update映皆,它會(huì)對(duì)讀取的行記錄加一個(gè)寫鎖捅彻,那么其他事務(wù)就不能對(duì)鎖定的行上加任何鎖步淹,要不然會(huì)被阻塞
-
MDL(meta data lock)鎖
作用:用于保證表中元數(shù)據(jù)的信息
例子:在會(huì)話A中,表開啟查詢事務(wù)后键闺,會(huì)自動(dòng)獲得一個(gè)MDL鎖辛燥,會(huì)話B就不可以執(zhí)行任何DDL語句的操作
DDL:創(chuàng)建挎塌、刪除内边、修改漠其、庫(kù)或表結(jié)構(gòu),對(duì)數(shù)據(jù)庫(kù)或表的結(jié)構(gòu)操作
注意:進(jìn)行DDL操作完成之前拴驮,必須等待持有表上的元數(shù)據(jù)鎖的事務(wù)提交或回滾莹汤。在DDL操作在執(zhí)行階段可能會(huì)短暫地需要表上的獨(dú)占鎖
-
意向鎖
意向鎖時(shí)表級(jí)鎖纲岭,有兩種意向鎖的類型止潮,分別為意向共享鎖和意向排他鎖
意向共享鎖(IS):指在一個(gè)數(shù)據(jù)行加共享鎖前必須線取得該表的IS鎖
意向排他鎖(IX):指在一個(gè)數(shù)據(jù)行加排他鎖前必須線取得該表的IX鎖
意向鎖的作用跟MDL類似喇闸,都是防止在事務(wù)進(jìn)行過程燃乍,執(zhí)行DDL語句的操作致數(shù)據(jù)的不一致宛琅。
InnoDB行鎖種類
在RR隔離級(jí)別下嘿辟,行鎖有三種
注意:鎖是加在索引上的红伦,如果字段沒有建索引,在更新某行記錄的時(shí)候會(huì)把整張表鎖住
-
單個(gè)行記錄的鎖(record lock)
更新同一行數(shù)據(jù)會(huì)出現(xiàn)鎖等待的現(xiàn)象
注意:
主鍵和唯一索引都是行記錄的鎖模式召调。
在RC隔離級(jí)別下某残,只有record lock記錄鎖模式
-
間隙鎖(GAP lock)
在RR這個(gè)事務(wù)隔離級(jí)別玻墅,為了避免幻讀現(xiàn)象澳厢,引入了Gap lock剩拢。但它只鎖定行記錄數(shù)據(jù)的范圍徐伐,不包含一記錄本身,即不允許在此范圍內(nèi)插入任何數(shù)據(jù)角雷。
注意:在RC隔離級(jí)別勺三,間隙鎖會(huì)失效
-
記錄鎖和間隙鎖的組合叫作next-key lock
Next-key lock 是記錄鎖 (Record Lock) 與間l隙鎖(Gap lock)的組合吗坚,當(dāng)InnoDB掃描索引記錄時(shí)商源,會(huì)先對(duì)選中的索引記錄加上記錄鎖(Record Lock)炊汹,再對(duì)索引記錄兩邊的間隙上加上間隙鎖(Gap lock)讨便。
注意:普通索引默認(rèn)的就是next-key lock模式
鎖等待死鎖
-
鎖等待
鎖等待是指一個(gè)事務(wù)過程中產(chǎn)生的鎖霸褒,其他事務(wù)需要等待一個(gè)事務(wù)釋放它的鎖废菱,才能棧用該資源殊轴。如果該事務(wù)一直不釋放袒炉,就需要持續(xù)等待下去我磁,直到超過鎖等待時(shí)間芋哭。
-
死鎖
死鎖是指兩個(gè)或兩個(gè)以的進(jìn)程在執(zhí)行過程中,因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象,就是所謂的鎖資源請(qǐng)求產(chǎn)生了回路現(xiàn)象斑鸦,即死循環(huán)
四種避免死鎖的方法
如果不同程序會(huì)并發(fā)存取多個(gè)表,或者設(shè)計(jì)多行記錄時(shí)墩虹,盡量以相同的順序訪問表
業(yè)務(wù)中盡量采用小事務(wù)诫钓,避免使用大事務(wù)菌湃,要及時(shí)提交或者回滾事務(wù)惧所,
在同一個(gè)事務(wù)中下愈,盡可能做到一次鎖定所需要的所有資源
對(duì)于非常容易產(chǎn)生死鎖的業(yè)務(wù)部分势似,可以嘗試使用升級(jí)鎖粒度