mysql數(shù)據(jù)庫在innodb引擎下會出現(xiàn)表鎖定和行鎖定并存情況额划,下面我們來分析一下這種場景下數(shù)據(jù)庫的加鎖機(jī)制和處理方式柬讨。
1、在MyISAM 引擎中只有表鎖巍虫,
LOCK TABLE my_tabl_name READ;? 用讀鎖鎖表吱韭,會阻塞其他事務(wù)修改表數(shù)據(jù)吆豹。
LOCK TABLE my_table_name WRITe; 用寫鎖鎖表,會阻塞其他事務(wù)讀和寫理盆。
默認(rèn)情況下讀請求會加讀鎖痘煤,寫請求寫鎖,并且是鎖定整個(gè)表猿规,因此大量讀的業(yè)務(wù)這種引擎效率很高衷快。
2、在Innodb引擎又支持行鎖坎拐,行鎖分為共享鎖烦磁,一個(gè)事務(wù)對一行的共享只讀鎖养匈。排它鎖哼勇,一個(gè)事務(wù)對一行的排他讀寫鎖都伪。
3、這兩中鎖定類型的鎖共存的問題
考慮這個(gè)例子:
事務(wù)A鎖住了表中的一行积担,讓這一行只能讀陨晶,不能寫。
之后帝璧,事務(wù)B申請整個(gè)表的寫鎖先誉。
如果事務(wù)B申請成功,那么理論上它就能修改表中的任意一行的烁,這與A持有的行鎖是沖突的褐耳。
數(shù)據(jù)庫需要避免這種沖突,就是說要讓B的申請被阻塞渴庆,直到A釋放了行鎖铃芦。
數(shù)據(jù)庫要怎么判斷這個(gè)沖突呢?
step1:判斷表是否已被其他事務(wù)用表鎖鎖表
step2:判斷表中的每一行是否已被行鎖鎖住襟雷。
注意step2中通過遍歷查詢刃滓,這樣的判斷方法效率實(shí)在不高,因?yàn)樾枰闅v整個(gè)表耸弄。
于是就有了意向鎖咧虎。
在意向鎖存在的情況下,事務(wù)A必須先申請表的意向共享鎖计呈,成功后再申請一行的行鎖砰诵。
在意向鎖存在的情況下,上面的判斷可以改成
step1:不變
step2:發(fā)現(xiàn)表上有意向共享鎖捌显,說明表中有些行被共享行鎖鎖住了胧砰,因此,事務(wù)B申請表的寫鎖會被阻塞苇瓣。
最終結(jié)論:
(1)申請意向鎖的動作是數(shù)據(jù)庫完成的尉间,就是說,事務(wù)A申請一行的行鎖的時(shí)候击罪,數(shù)據(jù)庫會自動先開始申請表的意向鎖哲嘲,不需要我們程序員使用代碼來申請。
(2)IX媳禁,IS是表級鎖眠副,不會和行級的X,S鎖發(fā)生沖突竣稽。只會和表級的X囱怕,S發(fā)生沖突
行級別的X和S按照普通的共享霍弹、排他規(guī)則即可。所以之前的示例中第2步不會沖突娃弓,只要寫操作不是同一行典格,就不會發(fā)生沖突。
備注:? IX? 意向排它鎖台丛,IS 意向讀鎖耍缴,X 排它鎖,S 共享鎖