-mysql-鎖2

聲明:本欄目所使用的素材都是凱哥學(xué)堂VIP學(xué)員所寫,學(xué)員有權(quán)匿名,對(duì)文章有最終解釋權(quán);凱哥學(xué)堂旨在促進(jìn)VIP學(xué)員互相學(xué)習(xí)的基礎(chǔ)上公開筆記。

表級(jí)鎖:

之前我們介紹了行級(jí)鎖,顧名思義行級(jí)鎖就只是鎖住一行或多行數(shù)據(jù),因?yàn)獒槍?duì)的是行去鎖的,因?yàn)橐粋€(gè)表格內(nèi)會(huì)有很多行數(shù)據(jù),要在這些數(shù)據(jù)中去鎖定其中幾行數(shù)據(jù),是比較耗費(fèi)資源。而表級(jí)鎖則是可以鎖住整個(gè)表,所以相對(duì)于行級(jí)來說沒那么耗費(fèi)資源,表級(jí)鎖有兩個(gè)模式:只讀模式和只寫模式,這和文件權(quán)限里的只讀只寫有點(diǎn)類似。 在一般情況下表格鎖并不經(jīng)常使用,在這里只是介紹一下如何使用表級(jí)鎖,和解鎖表級(jí)鎖,而且表級(jí)鎖的資料都可以在網(wǎng)絡(luò)上查找到,所以了解一下即可,在mysql官方也有表格鎖語法的文檔:

https://dev.mysql.com/doc/refman/5.6/en/lock-tables.html

使用只讀模式的表級(jí)鎖,語法:

LOCK TABLES 表名 READ

示例:

我們?cè)俅蜷_一個(gè)客戶端來看看能否使用SELECT語句查詢這個(gè)帶有表級(jí)鎖的表格的數(shù)據(jù):

因?yàn)槲覀兪褂玫氖侵蛔x模式的表級(jí)鎖,自然每個(gè)用戶都可以讀取、查詢這個(gè)表格的數(shù)據(jù),那么我們可以嘗試一下update這會(huì)對(duì)表格數(shù)據(jù)修改的語句能否執(zhí)行:

在行級(jí)鎖里即便某些行數(shù)據(jù)被上鎖了也還是能夠使用insert語句插入數(shù)據(jù)的,那么我們?cè)囈幌略诒砀矜i里是否能行得通:

從結(jié)果可以得知在表級(jí)鎖的只讀模式下,是不允許任何用戶對(duì)上鎖的表格進(jìn)行任何的修改的。

自然的delete語句也無法使用:

那么如何解鎖呢?看看解鎖時(shí)會(huì)發(fā)生什么,解鎖表級(jí)鎖的語法很簡單:

UNLOCK TABLES

示例:

使用只寫模式的表級(jí)鎖,語法:

LOCK TABLES 表名 WRITE

示例:

在表級(jí)鎖的只寫模式里,只有上鎖用戶可以對(duì)表格進(jìn)行寫入數(shù)據(jù),其他用戶是不可以寫入數(shù)據(jù)的,其他用戶就連使用SELECT語句查詢數(shù)據(jù)都不可以:

上鎖用戶可以使用insert語句插入數(shù)據(jù),其他用戶則不允許這個(gè)操作:

update語句也是一樣的:

還有delete語句:

如果用戶給一張表格上了表級(jí)鎖,那么這個(gè)用戶在給這個(gè)表格解鎖之前就只能操作這個(gè)表格,數(shù)據(jù)庫里的其他表格均不可以進(jìn)行任何的操作,如果操作就會(huì)報(bào)錯(cuò):

只寫模式的解鎖語法是一樣的,都是UNLOCK TABLES:

總結(jié)一下表級(jí)鎖,表級(jí)鎖就是針對(duì)表格進(jìn)行鎖定,相對(duì)于行級(jí)鎖沒那么耗資源,表級(jí)鎖有兩個(gè)模式,只讀模式和只寫模式,只讀模式下上鎖用戶和其他用戶都只能查詢數(shù)據(jù)不能寫入數(shù)據(jù),只寫模式下上鎖用戶可以進(jìn)行查詢數(shù)據(jù)和寫入數(shù)據(jù),其他用戶既不能查詢數(shù)據(jù),也不能寫入數(shù)據(jù),執(zhí)行任何SQL語句都會(huì)進(jìn)入等待狀態(tài),一直等到表格解鎖為止,當(dāng)表格解鎖的時(shí)候在等待中的事務(wù)會(huì)馬上被執(zhí)行。某個(gè)用戶對(duì)某個(gè)表格使用了表級(jí)鎖的話,就只能操作那個(gè)表格,數(shù)據(jù)庫里的其他表格均不可進(jìn)行任何操作。

悲觀鎖:

悲觀鎖(Pessimistic Lock)是一種概念、解決某些問題的模式,并不是一種特定的機(jī)制,悲觀鎖,正如其名,它指的是對(duì)數(shù)據(jù)被外界(包括本系統(tǒng)當(dāng)前的其他事務(wù),以及來自外部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度(悲觀),因此,在整個(gè)數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實(shí)現(xiàn),往往依靠數(shù)據(jù)庫提供的鎖機(jī)制(也只有數(shù)據(jù)庫層提供的鎖機(jī)制才能真正保證數(shù)據(jù)訪問的排他性,否則,即使在本系統(tǒng)中實(shí)現(xiàn)了加鎖機(jī)制,也無法保證外部系統(tǒng)不會(huì)修改數(shù)據(jù))。

所以簡單來說悲觀鎖就是很悲觀,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖,這樣別人想拿這個(gè)數(shù)據(jù)就會(huì)block直到它拿到鎖。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫里邊就用到了很多這種鎖機(jī)制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。

例如之前我們做的火車票務(wù)系統(tǒng)的小案例,就是使用的悲觀鎖的方式,在我們的代碼里都是借助于數(shù)據(jù)庫自帶的鎖機(jī)制完成的,當(dāng)用戶A在購票時(shí)用戶B就不能夠購票,或者購票失敗,這就是在整個(gè)數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài),具有很明顯的排他性(悲觀)。 代碼:

悲觀鎖的優(yōu)點(diǎn)與不足:

悲觀并發(fā)控制實(shí)際上是“先取鎖再訪問”的保守策略,為數(shù)據(jù)處理的安全提供了保證。但是在效率方面,處理加鎖的機(jī)制會(huì)讓數(shù)據(jù)庫產(chǎn)生額外的開銷,還有增加產(chǎn)生死鎖的機(jī)會(huì);另外,在只讀型事務(wù)處理中由于不會(huì)產(chǎn)生沖突,也沒必要使用鎖,這樣做只能增加系統(tǒng)負(fù)載;還有會(huì)降低了并行性,一個(gè)事務(wù)如果鎖定了某行數(shù)據(jù),其他事務(wù)就必須等待該事務(wù)處理完才可以處理那數(shù)據(jù)。

樂觀鎖:

樂觀鎖( Optimistic Locking ) 相對(duì)悲觀鎖而言,樂觀鎖假設(shè)認(rèn)為數(shù)據(jù)一般情況下不會(huì)造成沖突,所以在數(shù)據(jù)進(jìn)行提交更新的時(shí)候,才會(huì)正式對(duì)數(shù)據(jù)的沖突與否進(jìn)行檢測(cè),如果發(fā)現(xiàn)沖突了,則讓返回用戶錯(cuò)誤的信息,讓用戶決定如何去做。 相對(duì)于悲觀鎖,在對(duì)數(shù)據(jù)庫進(jìn)行處理的時(shí)候,樂觀鎖并不會(huì)使用數(shù)據(jù)庫提供的鎖機(jī)制。一般的實(shí)現(xiàn)樂觀鎖的方式就是記錄數(shù)據(jù)版本。

數(shù)據(jù)版本,為數(shù)據(jù)增加的一個(gè)版本標(biāo)識(shí)。當(dāng)讀取數(shù)據(jù)時(shí),將版本標(biāo)識(shí)的值一同讀出,數(shù)據(jù)每更新一次,同時(shí)對(duì)版本標(biāo)識(shí)進(jìn)行更新。當(dāng)我們提交更新的時(shí)候,判斷數(shù)據(jù)庫表對(duì)應(yīng)記錄的當(dāng)前版本信息與第一次取出來的版本標(biāo)識(shí)進(jìn)行比對(duì),如果數(shù)據(jù)庫表當(dāng)前版本號(hào)與第一次取出來的版本標(biāo)識(shí)值相等,則予以更新,否則認(rèn)為是過期數(shù)據(jù)。

所以實(shí)際上樂觀鎖和悲觀鎖一樣也是一種概念、解決某些業(yè)務(wù)需求的模式,并不是一種特定的機(jī)制,樂觀鎖的主要實(shí)現(xiàn)方式是我們開發(fā)人員自己通過在數(shù)據(jù)庫中增加一條存儲(chǔ)數(shù)據(jù)版本的列,然后通過代碼來判斷這些數(shù)據(jù)的版本,而不是借助數(shù)據(jù)庫自帶的鎖來完成的一種鎖定數(shù)據(jù)的模式。

例如我們假設(shè)一種情況:用戶A和用戶B同時(shí)在ATM機(jī)里往一個(gè)賬戶余額2000元的賬戶取款,兩個(gè)用戶都查詢到賬戶還有2000元,所以用戶A要取款1500,用戶B要取款1000,然后這兩個(gè)取款事務(wù)會(huì)同時(shí)提交,如果這個(gè)銀行的系統(tǒng)邏輯寫得不夠好的話,就會(huì)出現(xiàn)2000-1500-1000=-500的結(jié)果,賬戶余額就會(huì)出現(xiàn)負(fù)數(shù)。

示意圖:

在這種取款的情況下,如果使用悲觀鎖來鎖住數(shù)據(jù)的話,由于其排他性,那么另外一個(gè)用戶就無法查詢賬戶余額,只能處于等待狀態(tài),因?yàn)樵诒^鎖里在事務(wù)結(jié)束之前數(shù)據(jù)都是處于鎖定狀態(tài),而且在銀行在這種數(shù)據(jù)量大的地方,使用共享鎖這種行級(jí)鎖也耗費(fèi)資源。所以就需要用到樂觀鎖了,樂觀鎖只有在操作提交的時(shí)候才會(huì)去鎖定數(shù)據(jù)。在樂觀鎖中我們可以給數(shù)據(jù)設(shè)定一個(gè)版本號(hào),一旦這個(gè)數(shù)據(jù)發(fā)生修改,版本號(hào)就會(huì)發(fā)生變化,每一個(gè)操作都會(huì)先判斷版本號(hào)是否是最新的版本號(hào),不是的話就不允許操作,在樂觀鎖的實(shí)現(xiàn)過程中我們并不會(huì)使用到數(shù)據(jù)庫自帶的鎖,所以用戶們都可以任意的查詢或提交操作。

示意圖:

下面我們做一個(gè)簡單的取款系統(tǒng)來演示如何實(shí)現(xiàn)樂觀鎖:

先準(zhǔn)備一個(gè)表格里面填充一行數(shù)據(jù):

代碼示例:

運(yùn)行結(jié)果:

樂觀鎖的優(yōu)點(diǎn)與不足:

樂觀并發(fā)控制相信事務(wù)之間的數(shù)據(jù)競爭(data race)的概率是比較小的,因此盡可能直接做下去,直到提交的時(shí)候才去鎖定,所以不會(huì)產(chǎn)生任何鎖和死鎖。但如果直接簡單這么做,還是有可能會(huì)遇到不可預(yù)期的結(jié)果,例如兩個(gè)事務(wù)都讀取了數(shù)據(jù)庫的某一行,經(jīng)過修改以后寫回?cái)?shù)據(jù)庫,這時(shí)就遇到了問題。

臟讀簡介:

臟讀就是指當(dāng)一個(gè)事務(wù)正在訪問數(shù)據(jù),并且對(duì)數(shù)據(jù)進(jìn)行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中,這時(shí),另外一個(gè)事務(wù)也訪問這個(gè)數(shù)據(jù),然后使用了這個(gè)數(shù)據(jù)。因?yàn)檫@個(gè)【學(xué)Java,到凱哥學(xué)堂kaige123.com】數(shù)據(jù)是還沒有提交的數(shù)據(jù),那么另外一個(gè)事務(wù)讀到的這個(gè)數(shù)據(jù)是臟數(shù)據(jù)(Dirty Data),依據(jù)臟數(shù)據(jù)所做的操作可能是不正確的。

不可重復(fù)讀:

在一個(gè)事務(wù)內(nèi),多次讀同一個(gè)數(shù)據(jù)。在這個(gè)事務(wù)還沒有結(jié)束時(shí),另一個(gè)事務(wù)也訪問該同一數(shù)據(jù)。那么,在第一個(gè)事務(wù)的兩次讀數(shù)據(jù)之間。由于第二個(gè)事務(wù)的修改,那么第一個(gè)事務(wù)讀到的數(shù)據(jù)可能不一樣,這樣就發(fā)生了在一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的,因此稱為不可重復(fù)讀,即原始讀取不可重復(fù)。

幻讀:

幻讀是指當(dāng)事務(wù)不是獨(dú)立執(zhí)行時(shí)發(fā)生的一種現(xiàn)象,例如第一個(gè)事務(wù)對(duì)一個(gè)表中的數(shù)據(jù)進(jìn)行了修改,比如這種修改涉及到表中的“全部數(shù)據(jù)行”。同時(shí),第二個(gè)事務(wù)也修改這個(gè)表中的數(shù)據(jù),這種修改是向表中插入“一行新數(shù)據(jù)”。那么,以后就會(huì)發(fā)生操作第一個(gè)事務(wù)的用戶發(fā)現(xiàn)表中還存在沒有修改的數(shù)據(jù)行,就好象發(fā)生了幻覺一樣.一般解決幻讀的方法是增加范圍鎖RangeS,鎖定檢索范圍為只讀,這樣就避免了幻讀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,202評(píng)論 3 426
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,742評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,297評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,688評(píng)論 1 327
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,875評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,438評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,183評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,384評(píng)論 1 372
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,612評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評(píng)論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,093評(píng)論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,330評(píng)論 2 377

推薦閱讀更多精彩內(nèi)容