在mysql? innodb中的行鎖分為共享鎖和排他鎖
共享鎖:
名詞解釋:共享鎖又叫做讀鎖犬耻,所有的事務(wù)只能對其進(jìn)行讀操作不能寫操作,加上共享鎖后在事務(wù)結(jié)束之前其他事務(wù)只能再加共享鎖,除此之外其他任何類型的鎖都不能再加了化戳。
用法:SELECT `id` FROM ?table WHERE id in(1,2)?LOCK IN SHARE MODE?結(jié)果集的數(shù)據(jù)都會加共享鎖
排他鎖:
名詞解釋:若某個事物對某一行加上了排他鎖戴已,只能這個事務(wù)對其進(jìn)行讀寫,在此事務(wù)結(jié)束之前扳躬,其他事務(wù)不能對其進(jìn)行加任何鎖脆诉,其他進(jìn)程可以讀取,不能進(jìn)行寫操作,需等待其釋放贷币。
用法:SELECT `id` FROM mk_user WHERE id=1 FOR UPDATE
注意:由于在innodb中行鎖击胜,他是針對索引去鎖定該條數(shù)據(jù),而不是直接鎖定該條數(shù)據(jù)的役纹。
另外偶摔,在行鎖中,如果沒有設(shè)置索引促脉,InnoDB只能使用表鎖辰斋。下面就是例子:
首先我們先查看一下該表有哪些所以,然后把所有索引都刪除瘸味。接著就開始沒有索引的情況下進(jìn)行行鎖宫仗。
開啟事務(wù),然后今天查詢旁仿,同時進(jìn)行行鎖藕夫。但是不提交。
session2中我們對id=2數(shù)據(jù)進(jìn)行行鎖枯冈,結(jié)果發(fā)現(xiàn)毅贮,在等待狀態(tài),說明這個時候尘奏,session1在行鎖的時候滩褥,沒有找到索引,就鎖表了罪既,這也是為什么session2處于等待狀態(tài)铸题,只有seesion1? commit的時候,才能獲取數(shù)據(jù)琢感。
接著就看一下設(shè)置好索引以后得查詢
首先設(shè)置主鍵索引:
接著開始行鎖查詢
可以發(fā)現(xiàn)在行鎖執(zhí)行排他鎖的時候丢间,session1在沒有commit的情況下,session2進(jìn)行查詢是處于等待狀態(tài)驹针。
接著我們查詢不用數(shù)據(jù)得時候
可以看到烘挫,當(dāng)查詢不同數(shù)據(jù)的時候,就不會出現(xiàn)等待狀態(tài)。由此可以知道饮六,由于MySQL的行鎖是針對索引加的鎖其垄,不是針對記錄加的鎖,所以雖然是訪問不同行的記錄卤橄,但是如果是使用相同的索引鍵绿满,是會出現(xiàn)鎖沖突的。應(yīng)用設(shè)計的時候要注意這一點(diǎn)窟扑。怎么理解這句話呢喇颁,舉個例子
給tel設(shè)置一個普通索引
我們用session1進(jìn)行行鎖,查詢tel為123的 發(fā)現(xiàn)有兩條數(shù)據(jù)
我們用session2進(jìn)行行鎖嚎货,查詢tel為234的
發(fā)現(xiàn)沒有等待狀態(tài)橘霎,但是如果我們查詢tel為123且name為33的呢?
就會發(fā)現(xiàn)處于等待狀態(tài)殖属,這就是如果是使用相同的索引鍵姐叁,是會出現(xiàn)鎖沖突的的解釋。因為你session查詢tel 為123的洗显,此時還沒有提交外潜,處于行鎖狀態(tài),session2去查詢tel為123 name為33的墙懂,就會出現(xiàn)等待橡卤。
另外當(dāng)表有多個索引的時候,不同的事務(wù)可以使用不同的索引鎖定不同的行损搬,另外碧库,不論是使用主鍵索引、唯一索引或普通索引巧勤,InnoDB都會使用行鎖來對數(shù)據(jù)加鎖嵌灰。
解釋一下:
由于前面session1用過行鎖,查詢tel為123的颅悉,有兩條數(shù)據(jù)沽瞭,分別id為1和3的,此時剩瓶,這兩條數(shù)據(jù)處于鎖定狀態(tài)驹溃,當(dāng)session2查詢id為3的時候,由于這條數(shù)據(jù)處于鎖定狀態(tài)延曙,因此就出現(xiàn)了等待豌鹤。
另外出現(xiàn)的就是一個死鎖得問題,舉個例子枝缔。
session1 鎖定id為1的布疙,session2鎖定id為2的。此時,如果session1再去查找id為2的灵临,session2去查找id為1的截型,會出現(xiàn)什么情況呢?
這時候就出現(xiàn)了死鎖的情況儒溉,邏輯上就是:session1在等待session2去commit ,session2在等待session1去commit宦焦。然后就進(jìn)入死循環(huán)了。
看看到底有沒有死鎖呢睁搭,
show engine innodb status 查看一下mysql死鎖日志赶诊。能看打死鎖的原因笼平,我因為我前面執(zhí)行的兩句導(dǎo)致得园骆。