mysql默認(rèn)是表鎖還是行鎖 mysql行級(jí)鎖和表級(jí)鎖的區(qū)別?
mysql行級(jí)鎖和表級(jí)鎖的區(qū)別?1. 程序中非數(shù)據(jù)庫交互操作導(dǎo)致事務(wù)掛起將接口調(diào)用或者文件操作等這一類非數(shù)據(jù)庫交互操作嵌入在 SQL 事務(wù)代碼之中,那么整個(gè)事務(wù)很有可能因此掛起(接口不通等待超時(shí)或是上
mysql行級(jí)鎖和表級(jí)鎖的區(qū)別?
1. 程序中非數(shù)據(jù)庫交互操作導(dǎo)致事務(wù)掛起
將接口調(diào)用或者文件操作等這一類非數(shù)據(jù)庫交互操作嵌入在 SQL 事務(wù)代碼之中,那么整個(gè)事務(wù)很有可能因此掛起(接口不通等待超時(shí)或是上傳下載大附件)。
2. 事務(wù)中包含性能較差的查詢 SQL
事務(wù)中存在慢查詢,導(dǎo)致同一個(gè)事務(wù)中的其他 DML 無法及時(shí)釋放占用的行鎖,引起行鎖等待。
3. 單個(gè)事務(wù)中包含大量 SQL
通常是由于在事務(wù)代碼中加入 for 循環(huán)導(dǎo)致,雖然單個(gè) SQL 運(yùn)行很快,但是 SQL 數(shù)量一大,事務(wù)就會(huì)很慢。
4. 級(jí)聯(lián)更新 SQL 執(zhí)行時(shí)間較久
這類 SQL 容易讓人產(chǎn)生錯(cuò)覺,例如:update A set ... where ...in (select B) 這類級(jí)聯(lián)更新,不僅會(huì)占用 A 表上的行鎖,也會(huì)占用 B 表上的行鎖,當(dāng) SQL 執(zhí)行較久時(shí),很容易引起 B 表上的行鎖等待。
5. 磁盤問題導(dǎo)致的事務(wù)掛起
極少出現(xiàn)的情形,比如存儲(chǔ)突然離線,SQL 執(zhí)行會(huì)卡在內(nèi)核調(diào)用磁盤的步驟上,一直等待,事務(wù)無法提交。
綜上可以看出,如果事務(wù)長時(shí)間未提交,且事務(wù)中包含了 DML 操作,那么就有可能產(chǎn)生行鎖等待,引起報(bào)錯(cuò)。
mysql怎么查看是表鎖還是行鎖?
MyISAM不支持事物,所以這些隔離級(jí)別是沒有意義的。然后再說一下這些隔離級(jí)別和鎖之間的關(guān)系(如在InnoDB中,支持行級(jí)鎖):首先一個(gè)事物由begin開始,由commit(成功執(zhí)行)或rollback(執(zhí)行失敗,需要回滾)終止,所以考慮事物問題的時(shí)候要考慮到事物的整個(gè)生命周期,對同一行數(shù)據(jù)的加鎖解鎖操作是有可能多次執(zhí)行的,因此傳統(tǒng)的2 Phase Locking(2PL,兩階段鎖)才會(huì)有很多變種,最簡單的是只要先統(tǒng)一上鎖,后統(tǒng)一釋放鎖就可以了,不用考慮釋放鎖的時(shí)間,最嚴(yán)格的是所有的鎖一旦加上之后,必須要等到事物commit或rollback后才可以釋放。舉個(gè)例子,有一行數(shù)據(jù) a,有兩個(gè)事物T1,T21.read uncommittedT1對a進(jìn)行寫操作,寫之前加了寫鎖,寫之后但是commit前釋放了寫鎖,這時(shí)候T2是可以讀a的,由于T1還沒有commit,所以T2就發(fā)生了read uncommitted的情況。2.read committed還是1中的情況,如果T1把a(bǔ)的寫鎖一直保持到T1 commit成功之后再釋放,那么T2在T1 commit之前都是不可以讀a的,就可以避免read uncommitted,這就是read committed。但是這種隔離級(jí)別下,如果t1插入了一個(gè)以前不存在的新行b,t2是可以讀的,就造成了幻讀的情況。3.repeatable read為了避免幻讀,可以加謂詞鎖延遲新行的添加,比如T2要讀大于5的行,那么就加個(gè)謂詞鎖,使得大于5的行不能被添加進(jìn)去,這種實(shí)現(xiàn)基本上也是實(shí)現(xiàn)了serializable read基于鎖的事物只是一種方法,一般被成為悲觀并發(fā)控制。此外,還有:樂觀并發(fā)控制:執(zhí)行讀寫的時(shí)候不加鎖,commit的時(shí)候檢測是否有沖突,若沒有沖突commit成功,否則需要rollback,值得注意的是,雖然讀寫的時(shí)候沒有加鎖,但是檢測的時(shí)候是要加鎖的,否則2個(gè)沖突的事物可能同時(shí)檢測成功,這一點(diǎn)絕大多數(shù)材料里都沒有指出。MVCC:給每個(gè)數(shù)據(jù)一個(gè)版本號(hào),讀的時(shí)候完全不需要鎖,寫的時(shí)候看具體實(shí)現(xiàn),可以選擇樂觀并發(fā)控制,也可以選擇悲觀并發(fā)控制,這種實(shí)現(xiàn)很容易實(shí)現(xiàn)snapshot isolation(也是一種隔離級(jí)別,只不過沒有以上幾個(gè)名氣大,可以保證每個(gè)事物可以看到一個(gè)在它發(fā)生之前的數(shù)據(jù)庫完整實(shí)例)。
剖析MySQL InnoDB引擎的行鎖表鎖,怎樣利用鎖解決事務(wù)并發(fā)問題?
多個(gè)網(wǎng)絡(luò)用戶同時(shí)讀取同一數(shù)據(jù)庫表,并不會(huì)產(chǎn)生沖突,只有一部分讀另一部分寫或者大家都要寫數(shù)據(jù)庫時(shí)才會(huì)產(chǎn)生沖突,數(shù)據(jù)庫執(zhí)行的是并發(fā)操作,也就是說微觀上是串行操作,宏觀上是并行操作。mysql是網(wǎng)絡(luò)數(shù)據(jù)庫,支持多事務(wù)處理,為了保證數(shù)據(jù)庫的一致性,就要在訪問數(shù)據(jù)庫時(shí)合理運(yùn)用互斥機(jī)制。
了解這個(gè)機(jī)制就好辦了,常用的鎖有共享鎖,也就是讀鎖,排斥鎖也就是寫鎖,還有更新鎖,也就是更新操作時(shí)加的鎖,也可以歸類于寫鎖。如果已經(jīng)加了讀鎖了,就不要再加寫鎖了,防止數(shù)據(jù)不一致。如果有寫鎖了就不要再加寫鎖了,防止數(shù)據(jù)庫死鎖。