寧波東錢湖建設(shè)局網(wǎng)站中國(guó)seo排行榜
之前我們已經(jīng)用很多篇幅給大家講解了多個(gè)事務(wù)并發(fā)運(yùn)行的時(shí)候,如果同時(shí)要讀寫一批數(shù)據(jù),此時(shí)讀和寫時(shí)間的關(guān)系是如何協(xié)調(diào)的,畢竟要是你不協(xié)調(diào)好的話,可能就會(huì)有臟讀、不可重復(fù)讀、幻讀等一系列的問(wèn)題。
簡(jiǎn)單來(lái)說(shuō),臟讀、不可重復(fù)讀、幻讀,都是別人在更新數(shù)據(jù)的時(shí)候,你怎么讀的問(wèn)題,讀的不對(duì),那就有問(wèn)題,讀的方法對(duì)了,那就不存在這一系列問(wèn)題了。
而你要解決這一系列問(wèn)題,其實(shí)就是依靠之前我們給大家講的那套,基于undo log版本鏈條以及ReadView實(shí)現(xiàn)的mvcc機(jī)制。
現(xiàn)在開始我們接下來(lái)要用一系列的篇幅來(lái)研究另外一個(gè)問(wèn)題了,那就是當(dāng)有多個(gè)事務(wù)同時(shí)并發(fā)更新一行數(shù)據(jù)的時(shí)候,不就是會(huì)有臟寫的問(wèn)題嗎?
我們之前講過(guò),臟寫是絕對(duì)不允許的,那么這個(gè)臟寫是靠什么防止的呢?
說(shuō)白了,就是靠鎖機(jī)制,依靠鎖機(jī)制讓多個(gè)事務(wù)更新一行數(shù)據(jù)的時(shí)候串行化,避免同時(shí)更新一行數(shù)據(jù),今天我們就先對(duì)數(shù)據(jù)庫(kù)的鎖機(jī)制做一個(gè)初步的入門講解。
在MySQL里,假設(shè)有一行數(shù)據(jù)擺在那兒不動(dòng),此時(shí)有一個(gè)事務(wù)來(lái)了要更新這行數(shù)據(jù),這個(gè)時(shí)候他會(huì)先琢磨一下,看看這行數(shù)據(jù)此時(shí)有沒(méi)有人加鎖?
一看沒(méi)人加鎖,太好了,說(shuō)明他是第一個(gè)人,捷足先登了。
此時(shí)這個(gè)事務(wù)就會(huì)創(chuàng)建一個(gè)鎖,里面包含了自己的trx_id和等待狀態(tài),然后把鎖跟這行數(shù)據(jù)關(guān)聯(lián)在一起。
同時(shí)大家應(yīng)該還記得,更新一行數(shù)據(jù)必須把他所在的數(shù)據(jù)頁(yè)從磁盤文件里讀取到緩存頁(yè)里來(lái)才能更新的,所以說(shuō),此時(shí)這行數(shù)據(jù)和關(guān)聯(lián)的鎖數(shù)據(jù)結(jié)構(gòu),都是在內(nèi)存里的,大家要明確這一點(diǎn),如下圖。

大家注意看上面的那個(gè)圖,因?yàn)槭聞?wù)A給那行數(shù)據(jù)加了鎖,所以此時(shí)就可以說(shuō)那行數(shù)據(jù)已經(jīng)被加鎖了
那么既然被加鎖了,此時(shí)就不能再讓別人訪問(wèn)了!如果有朋友對(duì)加鎖的概念不了解,可能是對(duì)編程語(yǔ)言不太了解,其實(shí)這個(gè)就跟Java里的加鎖是一個(gè)概念。
現(xiàn)在呢,有另外一個(gè)事務(wù)B過(guò)來(lái)了,這個(gè)事務(wù)B就也想更新那行數(shù)據(jù),此時(shí)就會(huì)檢查一下,當(dāng)前這行數(shù)據(jù)有沒(méi)有別人加鎖
然而他一下子發(fā)現(xiàn),真是糟糕啊,事務(wù)A這家伙太不地道了,居然搶先給這行數(shù)據(jù)加鎖了,這怎么辦呢?
事務(wù)B這個(gè)時(shí)候一想,那行,我也加個(gè)鎖,然后等著排隊(duì)不就得了,這個(gè)時(shí)候事務(wù)B也會(huì)生成一個(gè)鎖數(shù)據(jù)結(jié)構(gòu),里面有他的trx_id,還有自己的等待狀態(tài),但是他因?yàn)槭窃谂抨?duì)等待,所以他的等待狀態(tài)就是true了,意思是我在等著呢,如下圖。

接著事務(wù)A這個(gè)時(shí)候更新完了數(shù)據(jù),就會(huì)把自己的鎖給釋放掉了。鎖一旦釋放了,他就會(huì)去找,此時(shí)還有沒(méi)有別人也對(duì)這行數(shù)據(jù)加鎖了呢?他會(huì)發(fā)現(xiàn)事務(wù)B也加鎖了
于是這個(gè)時(shí)候,就會(huì)把事務(wù)B的鎖里的等待狀態(tài)修改為false,然后喚醒事務(wù)B繼續(xù)執(zhí)行,此時(shí)事務(wù)B就獲取到鎖了,如下圖。

上述就是MySQL中鎖機(jī)制的一個(gè)最基本的原理,大家可以先好好理解一下,其實(shí)是跟Java里的鎖機(jī)制,思路是完全類似的,從這種簡(jiǎn)單的鎖里可以引申出很多其他的概念,比如讀寫鎖,共享鎖,獨(dú)占鎖,公平鎖,非公平鎖,等等。Java里的鎖,也同樣具備這些鎖的概念。