mysql怎么解決的幻讀 mysql如何解決幻讀

mysql可重復(fù)讀的幻讀解決方案

首先需要明確的就是“幻讀”概念: 隔離級(jí)別是可重復(fù)讀,在一個(gè)事務(wù)中前后兩次查詢,查到了其他事務(wù)insert進(jìn)來的數(shù)據(jù)。

創(chuàng)新互聯(lián)建站是一家專注于網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作與策劃設(shè)計(jì),渝水網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設(shè)十余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:渝水等地區(qū)。渝水做網(wǎng)站價(jià)格咨詢:18980820575

強(qiáng)調(diào)的是讀取到了其他事務(wù)插入進(jìn)來的數(shù)據(jù)。

下面來論證一下可重復(fù)讀下幻讀的解決方案

先明確一下,for update語法就是當(dāng)前讀,也就是查詢當(dāng)前已經(jīng)提交的數(shù)據(jù),并且是帶悲觀鎖的。沒有for update就是快照讀,也就是根據(jù)readView讀取的undolog中的數(shù)據(jù)。

如果按照以上猜想,那么整個(gè)執(zhí)行結(jié)果就違背了 可重復(fù)讀 的隔離級(jí)別了。

那么我們再假設(shè)select * from TABLE where d = 5 for update;這條語句鎖定的是所有被掃描到的數(shù)據(jù)。

這是因?yàn)門2階段的update會(huì)被阻塞住,畢竟所有被掃描到的記錄都被鎖定了。

按照上述推理過程,很顯然,即使鎖定所有掃描到的數(shù)據(jù)行,也依然存在幻讀的情況。違背了 可重復(fù)讀 的隔離級(jí)別。

針對(duì)這個(gè)情況,我們要解決幻讀的問題,那么就要求針對(duì)所有被掃描的記錄行以及還不存在的d=5的記錄行都給鎖住。

至此,當(dāng)前查詢結(jié)果完全滿足 可重復(fù)讀 的隔離級(jí)別。

通過以上推論,我們可以總結(jié)一下,在可重復(fù)讀的隔離級(jí)別下,解決幻讀除了需要鎖定所有掃描到的記錄行外,還需要鎖定行之間的間隙,也就是通過間隙鎖來解決幻讀的問題。

關(guān)于MySQL的幻讀問題,看這一篇就夠了

什么是幻讀?

幻讀指的是一個(gè)事務(wù)在前后兩次查詢同一個(gè)范圍的時(shí)候,后一次查詢看到了前一次查詢沒有看到的行。

首先快照讀是不存在幻讀的,只有當(dāng)前讀(實(shí)時(shí)讀)才存在幻讀的問題。

幻讀有什么問題?

select ...for update語句就是將相應(yīng)的數(shù)據(jù)行鎖住,但是如果存在幻讀,就把for update的語義破壞了。

如何解決幻讀?

產(chǎn)生幻讀的原因是,行鎖只能鎖住行,但是新插入記錄這個(gè)動(dòng)作,要更新的是記錄之間的“間隙”。因此,為了解決幻讀問題,InnoDB只好引入新的鎖,也就是間隙鎖(Gap Lock)。間隙鎖和行鎖合稱 next-key lock , 每個(gè)next-key lock是前開后閉區(qū)間 。

總結(jié)

正確理解MYSQL的幻讀

一、定義

1、幻讀MYSQL官方叫法是Phantom Rows,意為鬼影行或者幻影行,請看官方定義:

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.

翻譯一下:

所謂的幻影行問題是指,在同一個(gè)事務(wù)中,同樣的查詢語句執(zhí)行多次,得到了不同的行結(jié)果集。

例如,如果同一個(gè)SELECT語句執(zhí)行了兩次,第二次執(zhí)行的時(shí)候比第一次執(zhí)行時(shí)多出一行,則該行就是所謂的幻影行。

2、幻讀與不可重復(fù)讀的區(qū)別

從官方的定義來看,幻讀的定義側(cè)重于多條記錄,就是記錄條數(shù)的變化,而不可重復(fù)讀側(cè)重于單條記錄數(shù)據(jù)的變化,這樣區(qū)分原因在于解決幻讀需要范圍鎖,解決不可重復(fù)讀只需要單條記錄加鎖

二、InnoDB的REPEATABLE READ級(jí)別

InnoDB支持由SQL1992標(biāo)準(zhǔn)描述的所有四個(gè)事務(wù)隔離級(jí)別,默認(rèn)隔離級(jí)別是 REPEATABLE READ。

1、快照讀:

在RR模式下,第一次讀取會(huì)建立快照,后續(xù)查詢會(huì)讀取快照。

這意味著,如果在同一事務(wù)中發(fā)出多個(gè)普通[ SELECT ](非鎖定)語句,則這些 [ SELECT ]語句的結(jié)果也是一致的。

2、[locking reads](鎖定讀取,又叫當(dāng)前讀)

[ SELECT ]語句中使用 FOR UPDATE 或 FOR SHARE

3、行鎖

在RR模式下,使用當(dāng)前讀以及 [ UPDATE ]和 [ DELETE ]語句會(huì)對(duì)數(shù)據(jù)記錄加行鎖,鎖定范圍取決于該語句使用的是具有唯一搜索條件的唯一索引還是范圍類型搜索條件。

三、InnoDB的READ COMMITTED級(jí)別

1、在RC模式下,每次讀取都會(huì)刷新快照,因此不能保證可重復(fù)讀

2、在RC模式下,使用當(dāng)前讀以及 [ UPDATE ]和 [ DELETE ]語句會(huì)對(duì)數(shù)據(jù)記錄加行鎖,但是不會(huì)加范圍鎖,間隙鎖定僅用于外鍵約束檢查和重復(fù)鍵檢查。

3、由于禁用了間隙鎖定,因此可能會(huì)產(chǎn)生幻影行問題,因?yàn)槠渌麜?huì)話可以在間隙中插入新行。

4、 對(duì)于[ UPDATE ]或 [ DELETE ]語句, InnoDB 僅對(duì)其更新或刪除的行持有鎖。MySQL評(píng)估 WHERE 條件后,將釋放不匹配行的記錄鎖 。這大大降低了死鎖的可能性,但是仍然可以發(fā)生。

5、對(duì)于[ UPDATE ]語句,如果某行已被鎖定,則 InnoDB 執(zhí)行“半一致”讀取,將最新提交版本的數(shù)據(jù)返回給MySQL,以便MySQL可以確定該行是否符合 WHERE 條件。如果該行匹配(必須更新),則MySQL會(huì)再次讀取該行,這一次 InnoDB 會(huì)將其鎖定或等待獲取鎖。

6、注意

從MySQL 8.0.22開始,DML操作(增刪改,通過聯(lián)接列表或子查詢)從MySQL授權(quán)表中讀取數(shù)據(jù),但不對(duì)其進(jìn)行修改,無論隔離級(jí)別如何,都不會(huì)在MySQL授權(quán)表上獲得讀取鎖。

有關(guān)更多信息,請參見 Grant Table Concurrency 。

四、樂觀鎖與悲觀鎖

1、樂觀鎖

在UPDATE的WHERE子句中加入版本信息來確定修改是否生效

使用樂觀鎖時(shí)仍然需要非常謹(jǐn)慎,因?yàn)镽R是可重復(fù)讀的,在UPDATE之前讀取版本號(hào),應(yīng)該使用[當(dāng)前讀],不能使用[快照讀]

2、悲觀鎖

在UPDATE執(zhí)行前,SELECT后面加上FOR UPDATE來給記錄加鎖,保證記錄在UPDATE前不被修改。SELECT ... FOR UPDATE是加上了X鎖,也可以通過SELECT ... LOCK IN SHARE MODE加上S鎖,來防止其他事務(wù)對(duì)該行的修改。

3、無論是樂觀鎖還是悲觀鎖,使用的思想都是一致的,那就是當(dāng)前讀。樂觀鎖利用當(dāng)前讀判斷是否是最新版本,悲觀鎖利用當(dāng)前讀鎖定行。

五、總結(jié)

1、RC級(jí)別沒有范圍鎖一定會(huì)導(dǎo)致不可重復(fù)讀和幻影行

2、RR級(jí)別安全性更高,實(shí)現(xiàn)可重復(fù)讀的方式為快照,如果需要最新數(shù)據(jù)可以選擇[當(dāng)前讀],因此RR級(jí)別是首選

3、不論RR還是RC級(jí)別,增、刪、改的操作都會(huì)進(jìn)行一次[當(dāng)前讀]操作,以此獲取最新版本的數(shù)據(jù),并檢測是否有重復(fù)的索引。

4、RR級(jí)別下,當(dāng)前事務(wù)如果未發(fā)生更新操作(增刪改),快照版本會(huì)保持不變,多次查詢讀取的快照是同一個(gè)

5、RR級(jí)別下,當(dāng)前事務(wù)如果發(fā)生更新(增刪改),會(huì)刷新快照,會(huì)導(dǎo)致不可重復(fù)讀和幻影行

6、RR級(jí)別下,使用當(dāng)前讀,會(huì)刷新快照,會(huì)導(dǎo)致不可重復(fù)讀和幻影行

7、RR級(jí)別下,可以通過提交當(dāng)前事務(wù)并在此之后發(fā)出新查詢來為查詢獲取更新的快照。

8、RR級(jí)別可以部分解決不可重復(fù)讀和幻讀問題

9、其實(shí)問題的關(guān)鍵是你的業(yè)務(wù)邏輯需要可重復(fù)讀還是最新數(shù)據(jù)

分享文章:mysql怎么解決的幻讀 mysql如何解決幻讀
本文網(wǎng)址:http://m.kartarina.com/article46/dodsgeg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化Google做網(wǎng)站響應(yīng)式網(wǎng)站定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
主站蜘蛛池模板: 精品久久久无码中文字幕天天| 国产精品xxxx国产喷水亚洲国产精品无码久久一区| 无码少妇一区二区浪潮av| 下载天堂国产AV成人无码精品网站| 亚洲午夜无码AV毛片久久| 亚洲真人无码永久在线| 精品成在人线AV无码免费看| 无码人妻精品一区二| 无码人妻精品一区二区三区蜜桃 | 亚洲AV无码专区国产乱码电影| 精品少妇无码AV无码专区| 色欲香天天综合网无码| 亚洲真人无码永久在线观看| 国产精品ⅴ无码大片在线看| 无码国产精品一区二区高潮| 在线观看无码不卡AV| 亚洲VA中文字幕无码毛片| 无码专区6080yy国产电影| 亚洲av永久无码| 亚洲国产成AV人天堂无码| a级毛片无码免费真人久久| 无码人妻aⅴ一区二区三区| 久久久久亚洲av无码专区喷水| 亚洲中文字幕无码中文字在线| 少妇中文无码高清| 国产精品爽爽V在线观看无码| 亚洲中文字幕无码久久2020| 午夜人性色福利无码视频在线观看 | 亚洲国产精品无码专区在线观看 | 亚洲av无码国产精品色午夜字幕| 免费无码婬片aaa直播表情| 精品少妇人妻AV无码专区不卡| 亚洲av永久无码嘿嘿嘿| 久久久久亚洲AV无码网站| 亚洲AV无码不卡无码| 熟妇人妻AV无码一区二区三区| 亚洲av无码成人黄网站在线观看 | 亚洲av永久无码精品秋霞电影秋| 久久无码AV一区二区三区| 亚洲国产av高清无码| 亚洲av无码专区青青草原|