新聞中心
并發(fā)即指在同一時(shí)刻,多個(gè)操作并行執(zhí)行。MySQL對(duì)并發(fā)的處理主要應(yīng)用了兩種機(jī)制——是“鎖”和“多版本控制”。

公司主營(yíng)業(yè)務(wù):網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)推出謝通門免費(fèi)做網(wǎng)站回饋大家。
鎖
鎖分為讀鎖和寫鎖兩種,也稱作共享鎖和排他鎖。
因?yàn)槎鄠€(gè)讀操作同時(shí)進(jìn)行是不會(huì)破壞數(shù)據(jù)的,所以讀鎖是共享的,多個(gè)讀操作可以同時(shí)進(jìn)行,互不干擾。
為了防止多個(gè)寫操作共同執(zhí)行破壞數(shù)據(jù),寫鎖是排他的,一個(gè)寫鎖會(huì)阻塞其它的寫鎖和讀鎖,進(jìn)而保證同一資源在任何時(shí)刻只有一個(gè)寫操作在執(zhí)行,并防止其它用戶讀取正在寫入的該資源。
在鎖粒度方面,MySQL包括表鎖和行鎖兩種類型。鎖的粒度越小,越有利于對(duì)數(shù)據(jù)庫(kù)操作的并發(fā)執(zhí)行。但是管理鎖消耗的資源也會(huì)更多。如果系統(tǒng)花費(fèi)大量的時(shí)間來(lái)管理鎖,而不是存儲(chǔ)數(shù)據(jù),那么系統(tǒng)的性能也會(huì)受到影響。
表鎖會(huì)鎖定整張表,它是開(kāi)銷最小的策略。諸如ALTER TABLE之類的語(yǔ)句會(huì)使用表鎖。
行鎖***程度的支持并發(fā)操作,同時(shí)也帶來(lái)了***的開(kāi)銷。InnoDB實(shí)現(xiàn)了行鎖。
在MySql中并不只是用鎖來(lái)維護(hù)并發(fā)控制。
事務(wù)的隔離級(jí)別
事務(wù)的概念在此不多介紹。我覺(jué)得,也可以將事務(wù)看成是并發(fā)中的一部分——事務(wù)包含了一組操作,事務(wù)和事務(wù)之間可以并行執(zhí)行。事務(wù)和事務(wù)之間的并發(fā)也和普通的并發(fā)操作一樣會(huì)共享相同的資源,這樣并發(fā)執(zhí)行的事務(wù)之間就會(huì)相互影響。根據(jù)事務(wù)之間影響程度的不同,提出了事務(wù)的隔離級(jí)別這個(gè)概念,分別是READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE。
READ UNCOMMITTED就是一個(gè)事務(wù)對(duì)共享數(shù)據(jù)的修改馬上就能夠被另一個(gè)事務(wù)感知到,其實(shí)也就是沒(méi)有對(duì)修改操作做任何特殊處理。
SERIALIZABLE是通過(guò)加鎖的方式強(qiáng)制事務(wù)串行執(zhí)行,這樣可以避免幻讀。但這種方式會(huì)帶來(lái)大量鎖爭(zhēng)用問(wèn)題。
READ COMMITTED和REPEATABLE READ是基于MVCC的方式實(shí)現(xiàn)的。
MVCC多版本并發(fā)控制
MySql對(duì)于事務(wù)之間并發(fā)控制的實(shí)現(xiàn)并不是簡(jiǎn)單的使用行級(jí)鎖。MySql在讀操作時(shí)并不加鎖,只有在寫操作時(shí)才會(huì)對(duì)修改的資源加鎖。
MVCC保存了數(shù)據(jù)資源在不同時(shí)間點(diǎn)上的多個(gè)快照。根據(jù)事務(wù)開(kāi)始的時(shí)間不同,每個(gè)事務(wù)看到的數(shù)據(jù)快照版本是不一樣的。
InnoDB中的MVCC實(shí)現(xiàn):存儲(chǔ)引擎全局維護(hù)了一個(gè)系統(tǒng)版本號(hào),每開(kāi)啟一個(gè)新的事務(wù),這個(gè)系統(tǒng)版本號(hào)就會(huì)遞增。事務(wù)開(kāi)始時(shí)刻的系統(tǒng)版本號(hào),會(huì)作為這個(gè)事務(wù)本身的版本號(hào)。在每行記錄中,存儲(chǔ)引擎又在每行的后面保存兩個(gè)隱藏的列,分別保存這一行的開(kāi)始版本號(hào)和過(guò)期版本號(hào)。在REPEATABLE READ隔離級(jí)別下,MVCC的具體操作如下:
- INSERT
存儲(chǔ)引擎為新插入的每一行保存當(dāng)前的系統(tǒng)版本號(hào)作為這一行的開(kāi)始版本號(hào)。
- UPDATE
存儲(chǔ)引擎會(huì)新插入一行記錄,當(dāng)前的系統(tǒng)版本號(hào)就是新記錄行的開(kāi)始版本號(hào)。同時(shí)會(huì)將原來(lái)行的過(guò)期版本號(hào)設(shè)為當(dāng)前的系統(tǒng)版本號(hào)。
- DELETE
存儲(chǔ)引擎將刪除的記錄行的過(guò)期版本號(hào)設(shè)置為當(dāng)前的系統(tǒng)版本號(hào)。
- SELECT
當(dāng)讀取記錄時(shí),存儲(chǔ)引擎會(huì)選取滿足下面兩個(gè)條件的行作為讀取結(jié)果。
1. 讀取記錄行的開(kāi)始版本號(hào)必須早于當(dāng)前事務(wù)的版本號(hào)。也就是說(shuō),在當(dāng)前事務(wù)開(kāi)始之前,這條記錄已經(jīng)存在。在事務(wù)開(kāi)始之后才插入的行,事務(wù)不會(huì)看到。
2. 讀取記錄行的過(guò)期版本號(hào)必須晚于當(dāng)前事務(wù)的版本號(hào)。也就是說(shuō),當(dāng)前事務(wù)開(kāi)始的時(shí)候,這條記錄還沒(méi)有過(guò)期。在事務(wù)開(kāi)始之前就已經(jīng)過(guò)期的數(shù)據(jù)行,該事務(wù)也不會(huì)看到。
通過(guò)上面的描述,可以看到在存儲(chǔ)引擎中,同一時(shí)刻存儲(chǔ)了一個(gè)數(shù)據(jù)行的多個(gè)版本。每個(gè)事務(wù)會(huì)根據(jù)自己的版本號(hào)和每個(gè)數(shù)據(jù)行的開(kāi)始及過(guò)期版本號(hào)選擇讀取合適的數(shù)據(jù)行。
MVCC只在READ COMMITTED和REPEATABLE READ這兩個(gè)級(jí)別下工作。
當(dāng)前名稱:MySQL并發(fā)控制
文章地址:http://fisionsoft.com.cn/article/dpoppsh.html


咨詢
建站咨詢
