日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

詳解MySQL中事務(wù)隔離級(jí)別的實(shí)現(xiàn)原理

瀏覽:30日期:2023-10-06 12:55:54
前言

說(shuō)到數(shù)據(jù)庫(kù)事務(wù),大家腦子里一定很容易蹦出一堆事務(wù)的相關(guān)知識(shí),如事務(wù)的ACID特性,隔離級(jí)別,解決的問(wèn)題(臟讀,不可重復(fù)讀,幻讀)等等,但是可能很少有人真正的清楚事務(wù)的這些特性又是怎么實(shí)現(xiàn)的,為什么要有四個(gè)隔離級(jí)別。

今天我們就先來(lái)聊聊MySQL中事務(wù)的隔離性的實(shí)現(xiàn)原理,后續(xù)還會(huì)繼續(xù)出文章分析其他特性的實(shí)現(xiàn)原理。

當(dāng)然MySQL博大精深,文章疏漏之處在所難免,歡迎批評(píng)指正。

說(shuō)明

MySQL的事務(wù)實(shí)現(xiàn)邏輯是位于引擎層的,并且不是所有的引擎都支持事務(wù)的,下面的說(shuō)明都是以InnoDB引擎為基準(zhǔn)。

定義

隔離性(isolation)指的是不同事務(wù)先后提交并執(zhí)行后,最終呈現(xiàn)出來(lái)的效果是串行的,也就是說(shuō),對(duì)于事務(wù)來(lái)說(shuō),它在執(zhí)行過(guò)程中,感知到的數(shù)據(jù)變化應(yīng)該只有自己操作引起的,不存在其他事務(wù)引發(fā)的數(shù)據(jù)變化。

隔離性解決的是并發(fā)事務(wù)出現(xiàn)的問(wèn)題。

標(biāo)準(zhǔn)SQL隔離級(jí)別

隔離性最簡(jiǎn)單的實(shí)現(xiàn)方式就是各個(gè)事務(wù)都串行執(zhí)行了,如果前面的事務(wù)還沒(méi)有執(zhí)行完畢,后面的事務(wù)就都等待。但是這樣的實(shí)現(xiàn)方式很明顯并發(fā)效率不高,并不適合在實(shí)際環(huán)境中使用。

為了解決上述問(wèn)題,實(shí)現(xiàn)不同程度的并發(fā)控制,SQL的標(biāo)準(zhǔn)制定者提出了不同的隔離級(jí)別:未提交讀(read uncommitted)、提交讀(read committed)、可重復(fù)讀(repeatable read)、序列化讀(serializable)。其中最高級(jí)隔離級(jí)別就是序列化讀,而在其他隔離級(jí)別中,由于事務(wù)是并發(fā)執(zhí)行的,所以或多或少允許出現(xiàn)一些問(wèn)題。見(jiàn)以下的矩陣表:

隔離級(jí)別(+:允許出現(xiàn),-:不允許出現(xiàn)) 臟讀 不可重復(fù)讀 幻讀 未提交讀 + + + 提交讀 - + + 可重復(fù)讀 - - + 序列化讀 - - -

注意,MySQL的InnoDB引擎在提交讀級(jí)別通過(guò)MVCC解決了不可重復(fù)讀的問(wèn)題,在可重復(fù)讀級(jí)別通過(guò)間隙鎖解決了幻讀問(wèn)題,具體見(jiàn)下面的分析。

實(shí)現(xiàn)原理標(biāo)準(zhǔn)SQL事務(wù)隔離級(jí)別實(shí)現(xiàn)原理

我們上面遇到的問(wèn)題其實(shí)就是并發(fā)事務(wù)下的控制問(wèn)題,解決并發(fā)事務(wù)的最常見(jiàn)方式就是悲觀并發(fā)控制了(也就是數(shù)據(jù)庫(kù)中的鎖)。標(biāo)準(zhǔn)SQL事務(wù)隔離級(jí)別的實(shí)現(xiàn)是依賴鎖的,我們來(lái)看下具體是怎么實(shí)現(xiàn)的:

事務(wù)隔離級(jí)別 實(shí)現(xiàn)方式 未提交讀(RU) 事務(wù)對(duì)當(dāng)前被讀取的數(shù)據(jù)不加鎖; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對(duì)其加行級(jí)共享鎖,直到事務(wù)結(jié)束才釋放。 提交讀(RC) 事務(wù)對(duì)當(dāng)前被讀取的數(shù)據(jù)加行級(jí)共享鎖(當(dāng)讀到時(shí)才加鎖),一旦讀完該行,立即釋放該行級(jí)共享鎖; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對(duì)其加行級(jí)排他鎖,直到事務(wù)結(jié)束才釋放。 可重復(fù)讀(RR) 事務(wù)在讀取某數(shù)據(jù)的瞬間(就是開(kāi)始讀取的瞬間),必須先對(duì)其加行級(jí)共享鎖,直到事務(wù)結(jié)束才釋放; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對(duì)其加行級(jí)排他鎖,直到事務(wù)結(jié)束才釋放。 序列化讀(S)事務(wù)在讀取數(shù)據(jù)時(shí),必須先對(duì)其加表級(jí)共享鎖 ,直到事務(wù)結(jié)束才釋放; 事務(wù)在更新數(shù)據(jù)時(shí),必須先對(duì)其加表級(jí)排他鎖 ,直到事務(wù)結(jié)束才釋放。

可以看到,在只使用鎖來(lái)實(shí)現(xiàn)隔離級(jí)別的控制的時(shí)候,需要頻繁的加鎖解鎖,而且很容易發(fā)生讀寫的沖突(例如在RC級(jí)別下,事務(wù)A更新了數(shù)據(jù)行1,事務(wù)B則在事務(wù)A提交前讀取數(shù)據(jù)行1都要等待事務(wù)A提交并釋放鎖)。

為了不加鎖解決讀寫沖突的問(wèn)題,MySQL引入了MVCC機(jī)制,詳細(xì)可見(jiàn)我以前的分析文章:一文讀懂?dāng)?shù)據(jù)庫(kù)中的樂(lè)觀鎖和悲觀鎖和MVCC。

InnoDB事務(wù)隔離級(jí)別實(shí)現(xiàn)原理

在往下分析之前,我們有幾個(gè)概念需要先了解下:

1、鎖定讀和一致性非鎖定讀

鎖定讀:在一個(gè)事務(wù)中,主動(dòng)給讀加鎖,如SELECT ... LOCK IN SHARE MODE 和 SELECT ... FOR UPDATE。分別加上了行共享鎖和行排他鎖。鎖的分類可見(jiàn)我以前的分析文章:你應(yīng)該了解的MySQL鎖分類)。

https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html

一致性非鎖定讀:InnoDB使用MVCC向事務(wù)的查詢提供某個(gè)時(shí)間點(diǎn)的數(shù)據(jù)庫(kù)快照。查詢會(huì)看到在該時(shí)間點(diǎn)之前提交的事務(wù)所做的更改,而不會(huì)看到稍后或未提交的事務(wù)所做的更改(本事務(wù)除外)。也就是說(shuō)在開(kāi)始了事務(wù)之后,事務(wù)看到的數(shù)據(jù)就都是事務(wù)開(kāi)啟那一刻的數(shù)據(jù)了,其他事務(wù)的后續(xù)修改不會(huì)在本次事務(wù)中可見(jiàn)。

Consistent read是InnoDB在RC和RR隔離級(jí)別處理SELECT語(yǔ)句的默認(rèn)模式。一致性非鎖定讀不會(huì)對(duì)其訪問(wèn)的表設(shè)置任何鎖,因此,在對(duì)表執(zhí)行一致性非鎖定讀的同時(shí),其它事務(wù)可以同時(shí)并發(fā)的讀取或者修改它們。

https://dev.mysql.com/doc/refman/8.0/en/innodb-consistent-read.html

2、當(dāng)前讀和快照讀

當(dāng)前讀

讀取的是最新版本,像UPDATE、DELETE、INSERT、SELECT ... LOCK IN SHARE MODE、SELECT ... FOR UPDATE這些操作都是一種當(dāng)前讀,為什么叫當(dāng)前讀?就是它讀取的是記錄的最新版本,讀取時(shí)還要保證其他并發(fā)事務(wù)不能修改當(dāng)前記錄,會(huì)對(duì)讀取的記錄進(jìn)行加鎖。

快照讀

讀取的是快照版本,也就是歷史版本,像不加鎖的SELECT操作就是快照讀,即不加鎖的非阻塞讀;快照讀的前提是隔離級(jí)別不是未提交讀和序列化讀級(jí)別,因?yàn)槲刺峤蛔x總是讀取最新的數(shù)據(jù)行,而不是符合當(dāng)前事務(wù)版本的數(shù)據(jù)行,而序列化讀則會(huì)對(duì)表加鎖。

3、隱式鎖定和顯式鎖定

隱式鎖定

InnoDB在事務(wù)執(zhí)行過(guò)程中,使用兩階段鎖協(xié)議(不主動(dòng)進(jìn)行顯示鎖定的情況):

隨時(shí)都可以執(zhí)行鎖定,InnoDB會(huì)根據(jù)隔離級(jí)別在需要的時(shí)候自動(dòng)加鎖; 鎖只有在執(zhí)行commit或者rollback的時(shí)候才會(huì)釋放,并且所有的鎖都是在同一時(shí)刻被釋放。

顯式鎖定

InnoDB也支持通過(guò)特定的語(yǔ)句進(jìn)行顯示鎖定(存儲(chǔ)引擎層)

select ... lock in share mode //共享鎖select ... for update //排他鎖 MySQL Server層的顯示鎖定:

lock tableunlock table

了解完上面的概念后,我們來(lái)看下InnoDB的事務(wù)具體是怎么實(shí)現(xiàn)的(下面的讀都指的是非主動(dòng)加鎖的select)

事務(wù)隔離級(jí)別 實(shí)現(xiàn)方式 未提交讀(RU) 事務(wù)對(duì)當(dāng)前被讀取的數(shù)據(jù)不加鎖,都是當(dāng)前讀; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對(duì)其加行級(jí)共享鎖,直到事務(wù)結(jié)束才釋放。 提交讀(RC) 事務(wù)對(duì)當(dāng)前被讀取的數(shù)據(jù)不加鎖,且是快照讀; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對(duì)其加行級(jí)排他鎖(Record),直到事務(wù)結(jié)束才釋放。 通過(guò)快照,在這個(gè)級(jí)別MySQL就解決了不可重復(fù)讀的問(wèn)題 可重復(fù)讀(RR) 事務(wù)對(duì)當(dāng)前被讀取的數(shù)據(jù)不加鎖,且是快照讀; 事務(wù)在更新某數(shù)據(jù)的瞬間(就是發(fā)生更新的瞬間),必須先對(duì)其加行級(jí)排他鎖(Record,GAP,Next-Key),直到事務(wù)結(jié)束才釋放。 通過(guò)間隙鎖,在這個(gè)級(jí)別MySQL就解決了幻讀的問(wèn)題 序列化讀(S)事務(wù)在讀取數(shù)據(jù)時(shí),必須先對(duì)其加表級(jí)共享鎖 ,直到事務(wù)結(jié)束才釋放,都是當(dāng)前讀; 事務(wù)在更新數(shù)據(jù)時(shí),必須先對(duì)其加表級(jí)排他鎖 ,直到事務(wù)結(jié)束才釋放。

可以看到,InnoDB通過(guò)MVCC很好的解決了讀寫沖突的問(wèn)題,而且提前一個(gè)級(jí)別就解決了標(biāo)準(zhǔn)級(jí)別下會(huì)出現(xiàn)的幻讀和不可重復(fù)讀問(wèn)題,大大提升了數(shù)據(jù)庫(kù)的并發(fā)能力。

一些常見(jiàn)誤區(qū)幻讀到底包不包括了delete的情況?

不可重復(fù)讀:前后多次讀取一行,數(shù)據(jù)內(nèi)容不一致,針對(duì)其他事務(wù)的update和delete操作。為了解決這個(gè)問(wèn)題,使用行共享鎖,鎖定到事務(wù)結(jié)束(也就是RR級(jí)別,當(dāng)然MySQL使用MVCC在RC級(jí)別就解決了這個(gè)問(wèn)題)

幻讀:當(dāng)同一個(gè)查詢?cè)诓煌瑫r(shí)間生成不同的行集合時(shí)就是出現(xiàn)了幻讀,針對(duì)的是其他事務(wù)的insert操作,為了解決這個(gè)問(wèn)題,鎖定整個(gè)表到事務(wù)結(jié)束(也就是S級(jí)別,當(dāng)然MySQL使用間隙鎖在RR級(jí)別就解決了這個(gè)問(wèn)題)

網(wǎng)上很多文章提到幻讀和提交讀的時(shí)候,有的說(shuō)幻讀包括了delete的情況,有的說(shuō)delete應(yīng)該屬于提交讀的問(wèn)題,那到底真相如何呢?我們實(shí)際來(lái)看下MySQL的官方文檔(如下)

The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT) is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.https://dev.mysql.com/doc/refman/5.7/en/innodb-next-key-locking.html

可以看到,幻讀針對(duì)的是結(jié)果集前后發(fā)生變化,所以看起來(lái)delete的情況應(yīng)該歸為幻讀,但是我們實(shí)際分析下上面列出的標(biāo)準(zhǔn)SQL在RR級(jí)別的實(shí)現(xiàn)原理就知道,標(biāo)準(zhǔn)SQL的RR級(jí)別是會(huì)對(duì)查到的數(shù)據(jù)行加行共享鎖,所以這時(shí)候其他事務(wù)想刪除這些數(shù)據(jù)行其實(shí)是做不到的,所以在RR下,不會(huì)出現(xiàn)因delete而出現(xiàn)幻讀現(xiàn)象,也就是幻讀不包含delete的情況。

MVCC能解決了幻讀問(wèn)題?

網(wǎng)上很多文章會(huì)說(shuō)MVCC或者M(jìn)VCC+間隙鎖解決了幻讀問(wèn)題,實(shí)際上MVCC并不能解決幻讀問(wèn)題。如以下的例子:

begin;#假設(shè)users表為空,下面查出來(lái)的數(shù)據(jù)為空select * from users; #沒(méi)有加鎖#此時(shí)另一個(gè)事務(wù)提交了,且插入了一條id=1的數(shù)據(jù)select * from users; #讀快照,查出來(lái)的數(shù)據(jù)為空update users set name=’mysql’ where id=1;#update是當(dāng)前讀,所以更新成功,并生成一個(gè)更新的快照select * from users; #讀快照,查出來(lái)id為1的一條記錄,因?yàn)镸VCC可以查到當(dāng)前事務(wù)生成的快照commit;

可以看到前后查出來(lái)的數(shù)據(jù)行不一致,發(fā)生了幻讀。所以說(shuō)只有MVCC是不能解決幻讀問(wèn)題的,解決幻讀問(wèn)題靠的是間隙鎖。如下:

begin;#假設(shè)users表為空,下面查出來(lái)的數(shù)據(jù)為空select * from users lock in share mode; #加上共享鎖#此時(shí)另一個(gè)事務(wù)B想提交且插入了一條id=1的數(shù)據(jù),由于有間隙鎖,所以要等待select * from users; #讀快照,查出來(lái)的數(shù)據(jù)為空update users set name=’mysql’ where id=1;#update是當(dāng)前讀,由于不存在數(shù)據(jù),不進(jìn)行更新select * from users; #讀快照,查出來(lái)的數(shù)據(jù)為空commit;#事務(wù)B提交成功并插入數(shù)據(jù)

注意,RR級(jí)別下想解決幻讀問(wèn)題,需要我們顯式加鎖,不然查詢的時(shí)候還是不會(huì)加鎖的

以上就是詳解MySQL中事務(wù)隔離級(jí)別的實(shí)現(xiàn)原理的詳細(xì)內(nèi)容,更多關(guān)于MySQL 事務(wù)隔離級(jí)別的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: MySQL 數(shù)據(jù)庫(kù)
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品4hu.www| 日韩av午夜在线观看| 国产精品亚洲四区在线观看| 亚洲人成毛片在线播放女女| 亚洲一区亚洲| 中文亚洲欧美| 只有精品亚洲| 亚洲人成亚洲精品| 免费不卡在线视频| 亚洲女同中文字幕| 国产一区成人| 亚洲人亚洲人色久| 亚洲精品三级| 日韩中文字幕麻豆| 日韩高清不卡一区| 免费看一区二区三区| 成人高清一区| 国产精品av一区二区| 尤物在线精品| 亚洲乱码视频| 国产亚洲人成a在线v网站| 免费看久久久| 在线观看精品| 鲁大师成人一区二区三区| 日韩精品成人在线观看| 麻豆视频观看网址久久| 91嫩草亚洲精品| 亚洲电影在线一区二区三区| 亚洲欧洲一区| 日韩一区二区三区精品 | 日韩激情一区| 妖精视频成人观看www| 最新国产精品久久久| 国产精品日本一区二区三区在线| 久久成人av| 亚洲91视频| 四虎精品永久免费| 精品久久在线| 欧美日韩三区| 国产精久久久| 1024精品一区二区三区| 蜜桃av一区二区在线观看| 国产美女亚洲精品7777| 久久精品国产99久久| 日韩精品导航| 日韩国产一区二区三区| 中文无码久久精品| 国产一区二区三区亚洲综合| 狠狠久久婷婷| 久久精品xxxxx| 国产在线|日韩| 免费看日韩精品| 国产精品chinese| 国内激情久久| 欧美亚洲三级| 久久久国产亚洲精品| 亚洲精品在线国产| 高清一区二区| 亚洲另类黄色| 97视频热人人精品免费| 免费观看久久久4p| 不卡福利视频| 色婷婷精品视频| 日韩精品一区二区三区中文| 日韩一区亚洲二区| 日韩福利在线观看| 亚洲小说欧美另类婷婷| 国产欧美日韩精品一区二区三区| 欧美1级日本1级| 国产精品白丝久久av网站| 午夜日韩在线| 精品成人18| 日韩专区一卡二卡| 91精品国产自产在线观看永久∴ | 三上悠亚国产精品一区二区三区| 日韩欧美高清一区二区三区| 国产主播一区| 久久av超碰| 一区二区精彩视频| 久久久久久美女精品| 国产精品日本一区二区不卡视频 | 99视频精品全国免费| 国产剧情在线观看一区| 日韩午夜黄色| www.51av欧美视频| 国产精品99精品一区二区三区∴ | 国产精品网站在线看| 美美哒免费高清在线观看视频一区二区| 久久青青视频| 国产精品视频一区二区三区 | 欧美大黑bbbbbbbbb在线| 精品国产亚洲一区二区在线观看| 日韩精品三级| 久久亚洲不卡| 视频一区中文| 伊人久久在线| 久久一区精品| 911精品国产| 免费在线观看一区二区三区| 欧洲在线一区| 激情视频网站在线播放色| 国产精品片aa在线观看| 奶水喷射视频一区| 免费久久精品| 欧美91福利在线观看| 在线人成日本视频| 精品视频在线你懂得| 老鸭窝一区二区久久精品| 国产欧美一区二区三区国产幕精品| 综合在线一区| 亚洲三级视频| 亚洲美女91| 亚洲欧洲日韩| 少妇精品久久久一区二区三区| 在线视频日韩| 不卡在线一区| av一区二区高清| 日韩精品视频在线看| 亚洲小说春色综合另类电影| 久久夜色精品| 综合激情在线| 婷婷综合国产| 亚洲精品免费观看| 国产欧美日韩在线一区二区| 欧美日韩精品一区二区三区视频 | 在线免费观看亚洲| 男女男精品视频网| 综合激情五月婷婷| 一级成人国产| 日韩黄色av| 国产日产高清欧美一区二区三区| 欧美一区91| 免费亚洲一区| 激情黄产视频在线免费观看| 国产成人久久精品一区二区三区| 日韩综合一区| 日韩在线观看不卡| 国产综合色产| 日韩视频一区| 亚洲狼人精品一区二区三区| 日精品一区二区三区| 久久精品xxxxx| 精品国产麻豆| 成人看片网站| 好吊一区二区三区| 亚洲色图网站| 奇米狠狠一区二区三区| 国产精品亚洲综合色区韩国| 精品国产亚洲日本| 欧美天堂视频| 亚洲欧美日韩综合国产aⅴ| 亚洲精品极品| 国产精品亚洲片在线播放| 国产一区二区三区天码| 伊人精品一区| 色综合视频一区二区三区日韩 | 蜜芽一区二区三区| 欧美日本一区| 91一区二区三区四区| 图片区亚洲欧美小说区| 亚洲三级精品| 久久超碰99| 秋霞影院一区二区三区| 亚洲一区日本| 国产极品一区| 国内精品福利| 中文字幕av一区二区三区四区| 国产精品欧美在线观看| 久久男女视频| 影音先锋久久精品| 麻豆精品新av中文字幕| 亚洲成人不卡| 亚洲精品自拍| 国产91在线播放精品| 亚洲女同一区| 国产调教一区二区三区| 国产精品yjizz视频网| 日韩午夜免费| 国产精品一线天粉嫩av| 欧美精品资源| 日韩欧美在线精品| 久久电影tv| 日韩中文一区二区| 在线一区av| 日韩精品一区二区三区中文在线| 福利在线一区| 亚洲欧美日韩精品一区二区| 国产精品白丝一区二区三区| 欧美不卡视频| 国产精品久久久网站| 91久久久精品国产| 国产精品久久久久久妇女 | 久久男人天堂| 日韩精品导航| 免费av一区二区三区四区| 国产精品久久久网站| 亚洲欧美日韩综合国产aⅴ| 精品视频一区二区三区在线观看 | 国产精品videosex极品| 尤物在线精品|