mysql鎖從大方向分為全局鎖,表級(jí)鎖和行鎖屹逛,這篇文章我們主要講行鎖础废。
首先,我們需要明確罕模,行鎖是innodb引擎特有的评腺,這也是innodb很厲害的一點(diǎn)淑掌。
行鎖的類型有四種蒿讥,記錄鎖,間隙鎖抛腕,臨建鎖芋绸,插入意向鎖
在講這四種行鎖之前,我們需要明確它們的基礎(chǔ)担敌,也就是共享鎖和排他鎖摔敛,我們把這兩種稱為鎖的模式
? ? 共享鎖(S鎖):select lock in share mode,滿足讀讀共享全封,讀寫互斥
? ? 排它鎖(X鎖):select for update ; update, insert ,delete马昙,滿足寫寫互斥、讀寫互斥
下圖是這兩種鎖模式的兼容情況
現(xiàn)在回到四種行級(jí)鎖:
1.記錄鎖(Record Lock):鎖住的是一條記錄
2.間隙鎖(Gap Lock):只存在于可重復(fù)讀隔離級(jí)別刹悴,目的是為了解決可重復(fù)讀隔離級(jí)別下幻讀的現(xiàn)象行楞,限制一個(gè)區(qū)間在間隙鎖加鎖的情況下不能插入數(shù)據(jù),如(3土匀,5)子房,那么鎖期間4就無(wú)法被插入
產(chǎn)生間隙鎖的條件(RR事務(wù)隔離級(jí)別下;):
? ? 使用普通索引鎖定恒削;
? ? 使用多列唯一索引池颈;
? ? 使用唯一索引鎖定多行記錄。
間隙鎖設(shè)置:
? 首先查看 innodb_locks_unsafe_for_binlog 是否禁用:show variables like 'innodb_locks_unsafe_for_binlog';
? 查看結(jié)果:innodb_locks_unsafe_for_binlog:默認(rèn)值為OFF钓丰,即啟用間隙鎖躯砰。
? 因?yàn)榇藚?shù)是只讀模式,如果想要禁用間隙鎖携丁,需要修改 my.cnf(windows是my.ini) 重新啟動(dòng)才行琢歇。? ??
? ?# 在 my.cnf 里面的[mysqld]添加
? ?[mysqld]
? ? innodb_locks_unsafe_for_binlog = 1
? 具體事例分析:https://zhuanlan.zhihu.com/p/48269420
3.臨建索(Next-Key Lock):目的也是為了解決幻讀兰怠,是記錄鎖和行級(jí)鎖的組合,既可以限制一個(gè)區(qū)間不能插入數(shù)據(jù)李茫,還可以限制某行記錄不能被修改揭保,如(3,5],那么4無(wú)法插入魄宏,且5這條記錄不能被修改
4.插入意向鎖:一個(gè)事務(wù)在插入一條記錄的時(shí)候秸侣,需要判斷插入位置是否已被其他事務(wù)加了間隙鎖(next-key lock 也包含間隙鎖)。如果有的話宠互,插入操作就會(huì)發(fā)生阻塞味榛,直到擁有間隙鎖的那個(gè)事務(wù)提交為止(釋放間隙鎖的時(shí)刻),在此期間會(huì)生成一個(gè)插入意向鎖予跌,表明有事務(wù)想在某個(gè)區(qū)間插入新記錄搏色,但是現(xiàn)在處于等待狀態(tài)。
參考資料:https://xiaolincoding.com/mysql/lock/mysql_lock.html#%E5%85%A8%E5%B1%80%E9%94%81