mysql记录锁与互斥锁区别_MySQL的各种锁认知
一、相關(guān)名詞
|--表級(jí)鎖(鎖定整個(gè)表)
|--頁(yè)級(jí)鎖(鎖定一頁(yè))
|--行級(jí)鎖(鎖定一行)
|--共享鎖(S鎖,MyISAM 叫做讀鎖)
|--排他鎖(X鎖,MyISAM 叫做寫鎖)
|--悲觀鎖(抽象性,不真實(shí)存在這個(gè)鎖)
|--樂(lè)觀鎖(抽象性,不真實(shí)存在這個(gè)鎖)
二、InnoDB與MyISAM
Mysql 在5.5之前默認(rèn)使用 MyISAM 存儲(chǔ)引擎,之后使用 InnoDB 。查看當(dāng)前存儲(chǔ)引擎:
show variables like '%storage_engine%';
MyISAM 操作數(shù)據(jù)都是使用的表鎖,你更新一條記錄就要鎖整個(gè)表,導(dǎo)致性能較低,并發(fā)不高。當(dāng)然同時(shí)它也不會(huì)存在死鎖問(wèn)題。
而 InnoDB 與 MyISAM 的最大不同有兩點(diǎn):一是 InnoDB 支持事務(wù);二是 InnoDB 采用了行級(jí)鎖。也就是你需要修改哪行,就可以只鎖定哪行。
在 Mysql 中,行級(jí)鎖并不是直接鎖記錄,而是鎖索引。索引分為主鍵索引和非主鍵索引兩種,如果一條sql 語(yǔ)句操作了主鍵索引,Mysql 就會(huì)鎖定這條主鍵索引;如果一條語(yǔ)句操作了非主鍵索引,MySQL會(huì)先鎖定該非主鍵索引,再鎖定相關(guān)的主鍵索引。
InnoDB 行鎖是通過(guò)給索引項(xiàng)加鎖實(shí)現(xiàn)的,如果沒(méi)有索引,InnoDB 會(huì)通過(guò)隱藏的聚簇索引來(lái)對(duì)記錄加鎖。也就是說(shuō):如果不通過(guò)索引條件檢索數(shù)據(jù),那么InnoDB將對(duì)表中所有數(shù)據(jù)加鎖,實(shí)際效果跟表鎖一樣。因?yàn)闆](méi)有了索引,找到某一條記錄就得掃描全表,要掃描全表,就得鎖定表。
三、共享鎖與排他鎖
1.首先說(shuō)明:數(shù)據(jù)庫(kù)的增刪改操作默認(rèn)都會(huì)加排他鎖,而查詢不會(huì)加任何鎖。
|--共享鎖:對(duì)某一資源加共享鎖,自身可以讀該資源,其他人也可以讀該資源(也可以再繼續(xù)加共享鎖,即 共享鎖可多個(gè)共存),但無(wú)法修改。要想修改就必須等所有共享鎖都釋放完之后。語(yǔ)法為:
select * from table lock in share mode
|--排他鎖:對(duì)某一資源加排他鎖,自身可以進(jìn)行增刪改查,其他人無(wú)法進(jìn)行任何操作。語(yǔ)法為:
select * from table for update --增刪改自動(dòng)加了排他鎖
2.下面援引例子說(shuō)明(援自:http://blog.csdn.net/samjustin1/article/details/52210125):
這里用T1代表一個(gè)數(shù)據(jù)庫(kù)執(zhí)行請(qǐng)求,T2代表另一個(gè)請(qǐng)求,也可以理解為T1為一個(gè)線程,T2 為另一個(gè)線程。
例1:-------------------------------------------------------------------------------------------------------------------------------------
T1:select * from table lock in share mode(假設(shè)查詢會(huì)花很長(zhǎng)時(shí)間,下面的例子也都這么假設(shè))
T2:update table set column1='hello'
過(guò)程:
T1運(yùn)行(并加共享鎖)
T2運(yùn)行
If T1還沒(méi)執(zhí)行完
T2等......
else鎖被釋放
T2執(zhí)行
endif
T2 之所以要等,是因?yàn)?T2 在執(zhí)行 update 前,試圖對(duì) table 表加一個(gè)排他鎖,而數(shù)據(jù)庫(kù)規(guī)定同一資源上不能同時(shí)共存共享鎖和排他鎖。所以 T2 必須等 T1 執(zhí)行完,釋放了共享鎖,才能加上排他鎖,然后才能開(kāi)始執(zhí)行 update 語(yǔ)句。
例2:-------------------------------------------------------------------------------------------------------------------------------------
T1:select * from table lock in share mode
T2:select * from table lock in share mode
這里T2不用等待T1執(zhí)行完,而是可以馬上執(zhí)行。
分析:
T1運(yùn)行,則 table 被加鎖,比如叫l(wèi)ockAT2運(yùn)行,再對(duì) table 加一個(gè)共享鎖,比如叫l(wèi)ockB兩個(gè)鎖是可以同時(shí)存在于同一資源上的(比如同一個(gè)表上)。這被稱為共享鎖與共享鎖兼容。這意味著共享鎖不阻止其它人同時(shí)讀資源,但阻止其它人修改資源。
例3:-------------------------------------------------------------------------------------------------------------------------------------
T1:select * from table lock in share mode
T2:select * from table lock in share mode
T3:update table set column1='hello'
T2 不用等 T1 運(yùn)行完就能運(yùn)行,T3 卻要等 T1 和 T2 都運(yùn)行完才能運(yùn)行。因?yàn)?T3 必須等 T1 和 T2 的共享鎖全部釋放才能進(jìn)行加排他鎖然后執(zhí)行 update 操作。
例4:(死鎖的發(fā)生)-----------------------------------------------------------------------------------------------------------------
T1:begin transelect * from table lock in share modeupdate table set column1='hello'
T2:begin transelect * from table lock in share modeupdate table set column1='world'
假設(shè) T1 和 T2 同時(shí)達(dá)到 select,T1 對(duì) table 加共享鎖,T2 也對(duì) table 加共享鎖,當(dāng) T1 的 select 執(zhí)行完,準(zhǔn)備執(zhí)行 update 時(shí),根據(jù)鎖機(jī)制,T1 的共享鎖需要升級(jí)到排他鎖才能執(zhí)行接下來(lái)的 update.在升級(jí)排他鎖前,必須等 table 上的其它共享鎖(T2)釋放,同理,T2 也在等 T1 的共享鎖釋放。于是死鎖產(chǎn)生了。
例5:-------------------------------------------------------------------------------------------------------------------------------------
T1:begin tranupdate table set column1='hello' where id=10
T2:begin tranupdate table set column1='world' where id=20
這種語(yǔ)句雖然最為常見(jiàn),很多人覺(jué)得它有機(jī)會(huì)產(chǎn)生死鎖,但實(shí)際上要看情況
|--如果id是主鍵(默認(rèn)有主鍵索引),那么T1會(huì)一下子找到該條記錄(id=10的記錄),然后對(duì)該條記錄加排他鎖,T2,同樣,一下子通過(guò)索引定位到記錄,然后對(duì)id=20的記錄加排他鎖,這樣T1和T2各更新各的,互不影響。T2也不需要等。
|--如果id是普通的一列,沒(méi)有索引。那么當(dāng)T1對(duì)id=10這一行加排他鎖后,T2為了找到id=20,需要對(duì)全表掃描。但因?yàn)門1已經(jīng)為一條記錄加了排他鎖,導(dǎo)致T2的全表掃描進(jìn)行不下去(其實(shí)是因?yàn)門1加了排他鎖,數(shù)據(jù)庫(kù)默認(rèn)會(huì)為該表加意向鎖,T2要掃描全表,就得等該意向鎖釋放,也就是T1執(zhí)行完成),就導(dǎo)致T2等待。
死鎖怎么解決呢?一種辦法是,如下:
例6:-------------------------------------------------------------------------------------------------------------------------------------
T1:begin transelect * from table for updateupdate table set column1='hello'
T2:begin transelect * from table for updateupdate table set column1='world'
這樣,當(dāng) T1 的 select 執(zhí)行時(shí),直接對(duì)表加上了排他鎖,T2 在執(zhí)行 select 時(shí),就需要等 T1 事物完全執(zhí)行完才能執(zhí)行。排除了死鎖發(fā)生。但當(dāng)?shù)谌齻€(gè) user 過(guò)來(lái)想執(zhí)行一個(gè)查詢語(yǔ)句時(shí),也因?yàn)榕潘i的存在而不得不等待,第四個(gè)、第五個(gè) user 也會(huì)因此而等待。在大并發(fā)情況下,讓大家等待顯得性能就太友好了。
所以,有些數(shù)據(jù)庫(kù)這里引入了更新鎖(如Mssql,注意:Mysql不存在更新鎖)。
例7:-------------------------------------------------------------------------------------------------------------------------------------
T1:begin transelect * from table (加更新鎖)update table set column1='hello'
T2:begin transelect * from table (加更新鎖)update table set column1='world'
更新鎖其實(shí)就可以看成排他鎖的一種變形,只是它也允許其他人讀(并且還允許加共享鎖)。但不允許其他操作,除非我釋放了更新鎖。T1 執(zhí)行 select,加更新鎖。T2 運(yùn)行,準(zhǔn)備加更新鎖,但發(fā)現(xiàn)已經(jīng)有一個(gè)更新鎖在那兒了,只好等。當(dāng)后來(lái)有 user3、user4...需要查詢 table 表中的數(shù)據(jù)時(shí),并不會(huì)因?yàn)?T1 的 select 在執(zhí)行就被阻塞,照樣能查詢,相比起例6,這提高了效率。
后面還有意向鎖和計(jì)劃鎖:意向鎖即是:某行修改時(shí),自動(dòng)加上了排他鎖,同時(shí)會(huì)默認(rèn)給該表加意向鎖,表示里面有記錄正被鎖定,這時(shí),其他人就不可以對(duì)該表加表鎖了。如果沒(méi)有意向鎖這個(gè)類似指示燈的東西存在,其他人加表鎖之前就得掃描全表,查看是否有記錄正被鎖定,效率低下。而計(jì)劃鎖這些,和程序員關(guān)系不大,就沒(méi)去了解了。
悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖,這樣別人想拿這個(gè)數(shù)據(jù)就會(huì)block直到它拿到鎖。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)里邊就用到了很多這種鎖機(jī)制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
樂(lè)觀鎖(Optimistic Lock), 顧名思義,就是很樂(lè)觀,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會(huì)修改,所以不會(huì)上鎖,但是在更新的時(shí)候會(huì)判斷一下在此期間別人有沒(méi)有去更新這個(gè)數(shù)據(jù),可以使用版本號(hào)等機(jī)制。樂(lè)觀鎖適用于多讀的應(yīng)用類型,這樣可以提高吞吐量,像數(shù)據(jù)庫(kù)如果提供類似于write_condition機(jī)制的其實(shí)都是提供的樂(lè)觀鎖。
兩種鎖各有優(yōu)缺點(diǎn),不可認(rèn)為一種好于另一種,像樂(lè)觀鎖適用于寫比較少的情況下,即沖突真的很少發(fā)生的時(shí)候,這樣可以省去了鎖的開(kāi)銷,加大了系統(tǒng)的整個(gè)吞吐量。但如果經(jīng)常產(chǎn)生沖突,上層應(yīng)用會(huì)不斷的進(jìn)行retry,這樣反倒是降低了性能,所以這種情況下用悲觀鎖就比較合適。
擴(kuò)展:
本質(zhì)上,數(shù)據(jù)庫(kù)的樂(lè)觀鎖做法和悲觀鎖做法主要就是解決下面假設(shè)的場(chǎng)景,避免丟失更新問(wèn)題: 一個(gè)比較清楚的場(chǎng)景 下面這個(gè)假設(shè)的實(shí)際場(chǎng)景可以比較清楚的幫助我們理解這個(gè)問(wèn)題: 假設(shè)當(dāng)當(dāng)網(wǎng)上用戶下單買了本書,這時(shí)數(shù)據(jù)庫(kù)中有條訂單號(hào)為001的訂單,其中有個(gè)status字段是’有效’,表示該訂單是有效的; 后臺(tái)管理人員查詢到這條001的訂單,并且看到狀態(tài)是有效的 用戶發(fā)現(xiàn)下單的時(shí)候下錯(cuò)了,于是撤銷訂單,假設(shè)運(yùn)行這樣一條SQL: update order_table set status = ‘取消’ where order_id = 001; 后臺(tái)管理人員由于在b這步看到狀態(tài)有效的,這時(shí),雖然用戶在c這步已經(jīng)撤銷了訂單,可是管理人員并未刷新界面,看到的訂單狀態(tài)還是有效的,于是點(diǎn)擊”發(fā)貨”按鈕,將該訂單發(fā)到物流部門,同時(shí)運(yùn)行類似如下SQL,將訂單狀態(tài)改成已發(fā)貨:update order_table set status = ‘已發(fā)貨’ where order_id = 001
觀點(diǎn)1:只有沖突非常嚴(yán)重的系統(tǒng)才需要悲觀鎖;“所有悲觀鎖的做法都適合于狀態(tài)被修改的概率比較高的情況,具體是否合適則需要根據(jù)實(shí)際情況判斷?!?#xff0c;表達(dá)的也是這個(gè)意思,不過(guò)說(shuō)法不夠準(zhǔn)確;的確,之所以用悲觀鎖就是因?yàn)閮蓚€(gè)用戶更新同一條數(shù)據(jù)的概率高,也就是沖突比較嚴(yán)重的情況下,所以才用悲觀鎖。
觀點(diǎn)2:最后提交前作一次select for update檢查,然后再提交update也是一種樂(lè)觀鎖的做法,的確,這符合傳統(tǒng)樂(lè)觀鎖的做法,就是到最后再去檢查。但是wiki在解釋悲觀鎖的做法的時(shí)候,’It is not appropriate for use in web application development.’, 現(xiàn)在已經(jīng)很少有悲觀鎖的做法了,所以我自己將這種二次檢查的做法也歸為悲觀鎖的變種,因?yàn)檫@在所有樂(lè)觀鎖里面,做法和悲觀鎖是最接近的,都是先select for update,然后update
在實(shí)際應(yīng)用中我們?cè)诟聰?shù)據(jù)的時(shí)候,更嚴(yán)謹(jǐn)?shù)淖龇ㄊ菐细虑暗摹盃顟B(tài)”,如
update order_table set status = ‘取消’ where order_id = 001 and status = ‘待支付’ and ..........;
update order_table set status = ‘已發(fā)貨’ where order_id = 001 and status = ‘已支付’ and ..........;
然后在業(yè)務(wù)邏輯代碼里判斷更新的記錄數(shù),為0說(shuō)明數(shù)據(jù)庫(kù)已經(jīng)被更新了,否則是正常的。
行鎖,表鎖
InnoDB存儲(chǔ)引擎中有行鎖以及表鎖,行鎖是InnoDB中默認(rèn)的鎖。
表鎖:對(duì)整張表進(jìn)行加鎖,在同一時(shí)刻整張表的所有記錄都被鎖住。
行鎖:只對(duì)表中的某一行記錄進(jìn)行加鎖,表的其余行不會(huì)被占用,但是可能會(huì)出現(xiàn)死鎖。
關(guān)閉事務(wù)自動(dòng)提交
查看一下表數(shù)據(jù)
接著我們更新一條數(shù)據(jù)
執(zhí)行成功之后我們并沒(méi)有提交事務(wù),這個(gè)時(shí)候這一條記錄已經(jīng)是加了鎖的,所以我們?cè)诹硗庖粋€(gè)客戶端更新同樣的行記錄。
自然就報(bào)錯(cuò)了,直接就等待超時(shí)了。這里證明已經(jīng)加鎖了,接著我們來(lái)證明是行鎖還是表鎖。
當(dāng)我們執(zhí)行update的時(shí)候,是update 字段a=1的 所以我們?cè)趗pdate字段a=2的時(shí)候,雖然沒(méi)有提交事務(wù)但是還是可以執(zhí)行的,這里證明了InnoDB是行鎖的。
注意:行鎖必須有索引才能實(shí)現(xiàn),否則就會(huì)自動(dòng)鎖住全表,也就是表鎖,而InnoDB當(dāng)有主鍵的時(shí)候,自動(dòng)就會(huì)創(chuàng)建主鍵索引。
行鎖與表鎖的區(qū)別
行鎖
優(yōu)點(diǎn) :粒度小, 因?yàn)榧渔i的只是一行數(shù)據(jù)。
缺點(diǎn) :獲取、釋放所需要做的工作更多,并且容易發(fā)生死鎖。
鎖的優(yōu)化:
合理設(shè)計(jì)索引
減少基于范圍的數(shù)據(jù)檢索過(guò)濾條件
盡量控制事務(wù)的大小,盡量使用較低的事務(wù)隔離級(jí)別
盡可能讓所有的數(shù)據(jù)檢索都通過(guò)索引來(lái)完成。
表鎖
優(yōu)點(diǎn):獲取跟釋放快,能避免死鎖(當(dāng)執(zhí)行update語(yǔ)句的時(shí)候,把整個(gè)表鎖住了,其他的sql無(wú)法執(zhí)行,所以不會(huì)造成死鎖)
缺點(diǎn):粒度太大,并發(fā)不夠高,當(dāng)并發(fā)量較多的時(shí)候,鎖表會(huì)讓進(jìn)程無(wú)法繼續(xù)執(zhí)行sql。
死鎖
死鎖出現(xiàn)在行鎖中,假設(shè)現(xiàn)在有一個(gè)T1的session線程去update一個(gè)數(shù)據(jù)庫(kù)表table1 ,而且有一個(gè)T2的session線程去update一個(gè)數(shù)據(jù)庫(kù)表table2。
在沒(méi)有提交事務(wù)的時(shí)候,table1跟table2都已經(jīng)進(jìn)行了加鎖,這個(gè)時(shí)候,T1去操作了table2,那么這個(gè)時(shí)候因?yàn)閠able2的記錄加了鎖,那么T1會(huì)一直在等待,接著T2又同樣的去操作table1的表記錄,也同樣在等待,就造成了死鎖。
InnoDB 支持多粒度鎖(multiple granularity locking),它允許行級(jí)鎖與表級(jí)鎖共存,而意向鎖就是其中的一種表鎖。
意向鎖(Intention Locks)
需要強(qiáng)調(diào)一下,意向鎖是一種不與行級(jí)鎖沖突的表級(jí)鎖,這一點(diǎn)非常重要。意向鎖分為兩種:
意向共享鎖 (intention shared lock, IS):事務(wù)有意向?qū)Ρ碇械哪承┬屑?共享鎖 (S鎖) -- 事務(wù)要獲取某些行的 S 鎖,必須先獲得表的 IS 鎖。 SELECT column FROM table ... LOCK IN SHARE MODE;
意向排他鎖 (intention exclusive lock, IX):事務(wù)有意向?qū)Ρ碇械哪承┬屑?排他鎖 (X鎖) -- 事務(wù)要獲取某些行的 X 鎖,必須先獲得表的 IX 鎖。 SELECT column FROM table ... FOR UPDATE;
即:意向鎖是有數(shù)據(jù)引擎自己維護(hù)的,用戶無(wú)法手動(dòng)操作意向鎖,在為數(shù)據(jù)行加共享 / 排他鎖之前,InooDB 會(huì)先獲取該數(shù)據(jù)行所在在數(shù)據(jù)表的對(duì)應(yīng)意向鎖。
意向鎖要解決的問(wèn)題
我們先來(lái)看一下百度百科上對(duì)意向鎖存在意義的描述:
如果另一個(gè)任務(wù)試圖在該表級(jí)別上應(yīng)用共享或排它鎖,則受到由第一個(gè)任務(wù)控制的表級(jí)別意向鎖的阻塞。第二個(gè)任務(wù)在鎖定該表前不必檢查各個(gè)頁(yè)或行鎖,而只需檢查表上的意向鎖。
設(shè)想這樣一張 users 表:MySql,InnoDB,Repeatable-Read:users(id PK,name)
事務(wù) A 獲取了某一行的排他鎖,并未提交:
SELECT * FROM users WHERE id = 6 FOR UPDATE;
事務(wù) B 想要獲取 users 表的表鎖:
LOCK TABLES users READ;
因?yàn)楣蚕礞i與排他鎖互斥,所以事務(wù) B 在視圖對(duì) users 表加共享鎖的時(shí)候,必須保證:
當(dāng)前沒(méi)有其他事務(wù)持有 users 表的排他鎖。
當(dāng)前沒(méi)有其他事務(wù)持有 users 表中任意一行的排他鎖 。
為了檢測(cè)是否滿足第二個(gè)條件,事務(wù) B 必須在確保 users表不存在任何排他鎖的前提下,去檢測(cè)表中的每一行是否存在排他鎖。很明顯這是一個(gè)效率很差的做法,但是有了意向鎖之后,情況就不一樣了:
意向鎖的兼容互斥性
意向鎖是怎么解決這個(gè)問(wèn)題的呢?首先,我們需要知道意向鎖之間的兼容互斥性:
即意向鎖之間是互相兼容的,emmm......那你存在的意義是啥?
雖然意向鎖和自家兄弟互相兼容,但是它會(huì)與普通的排他 / 共享鎖互斥:
注意:這里的排他 / 共享鎖指的都是表鎖!!!意向鎖不會(huì)與行級(jí)的共享 / 排他鎖互斥!!!
現(xiàn)在我們回到剛才 users 表的例子:
事務(wù) A 獲取了某一行的排他鎖,并未提交:
SELECT * FROM users WHERE id = 6 FOR UPDATE;
此時(shí) users 表存在兩把鎖:users 表上的意向排他鎖與 id 為 6 的數(shù)據(jù)行上的排他鎖。
事務(wù) B 想要獲取 users 表的共享鎖:
LOCK TABLES users READ;
此時(shí)事務(wù) B 檢測(cè)事務(wù) A 持有 users 表的意向排他鎖,就可以得知事務(wù) A 必然持有該表中某些數(shù)據(jù)行的排他鎖,那么事務(wù) B 對(duì) users 表的加鎖請(qǐng)求就會(huì)被排斥(阻塞),而無(wú)需去檢測(cè)表中的每一行數(shù)據(jù)是否存在排他鎖。
意向鎖的并發(fā)性
這就牽扯到我前面多次強(qiáng)調(diào)的一件事情:
意向鎖不會(huì)與行級(jí)的共享 / 排他鎖互斥!!!意向鎖不會(huì)與行級(jí)的共享 / 排他鎖互斥!!!意向鎖不會(huì)與行級(jí)的共享 / 排他鎖互斥!!!
重要的話要加粗說(shuō)三遍,正因?yàn)槿绱?#xff0c;意向鎖并不會(huì)影響到多個(gè)事務(wù)對(duì)不同數(shù)據(jù)行加排他鎖時(shí)的并發(fā)性(不然我們直接用普通的表鎖就行了)。
最后我們擴(kuò)展一下上面 users 表的例子來(lái)概括一下意向鎖的作用(一條數(shù)據(jù)從被鎖定到被釋放的過(guò)程中,可能存在多種不同鎖,但是這里我們只著重表現(xiàn)意向鎖):
事務(wù) A 先獲取了某一行的排他鎖,并未提交:
SELECT * FROM users WHERE id = 6 FOR UPDATE;
事務(wù) A 獲取了 users 表上的意向排他鎖。
事務(wù) A 獲取了 id 為 6 的數(shù)據(jù)行上的排他鎖。
之后事務(wù) B 想要獲取 users 表的共享鎖:
LOCK TABLES users READ;
事務(wù) B 檢測(cè)到事務(wù) A 持有 users 表的意向排他鎖。
事務(wù) B 對(duì) users 表的加鎖請(qǐng)求被阻塞(排斥)。
最后事務(wù) C 也想獲取 users 表中某一行的排他鎖:
SELECT * FROM users WHERE id = 5 FOR UPDATE;
事務(wù) C 申請(qǐng) users 表的意向排他鎖。
事務(wù) C 檢測(cè)到事務(wù) A 持有 users 表的意向排他鎖。
因?yàn)橐庀蜴i之間并不互斥,所以事務(wù) C 獲取到了 users 表的意向排他鎖。
因?yàn)閕d 為 5 的數(shù)據(jù)行上不存在任何排他鎖,最終事務(wù) C 成功獲取到了該數(shù)據(jù)行上的排他鎖。
總結(jié)
InnoDB 支持多粒度鎖,特定場(chǎng)景下,行級(jí)鎖可以與表級(jí)鎖共存。
意向鎖之間互不排斥,但除了 IS 與 S 兼容外,意向鎖會(huì)與 共享鎖 / 排他鎖 互斥。
IX,IS是表級(jí)鎖,不會(huì)和行級(jí)的X,S鎖發(fā)生沖突。只會(huì)和表級(jí)的X,S發(fā)生沖突。
意向鎖在保證并發(fā)性的前提下,實(shí)現(xiàn)了行鎖和表鎖共存且滿足事務(wù)隔離性的要求。
總結(jié)
以上是生活随笔為你收集整理的mysql记录锁与互斥锁区别_MySQL的各种锁认知的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: sql远程mysql服务器查询_sql
- 下一篇: php编程怎么和mysql链接_php编