0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

MySQL事務(wù)隔離級別要實(shí)際解決的問題

冬至子 ? 來源:后端元宇宙 ? 作者:binron ? 2022-11-17 17:00 ? 次閱讀

在MySQL的眾多存儲(chǔ)引擎中,只有InnoDB支持事務(wù),所有這里說的事務(wù)隔離級別指的是InnoDB下的事務(wù)隔離級別。

MySQL 是支持多事務(wù)并發(fā)執(zhí)行的。否則來一個(gè)事務(wù)處理一個(gè)請求,處理一個(gè)人請求的時(shí)候,其它事務(wù)都等著,那估計(jì)都沒人敢用MySQL作為數(shù)據(jù)庫,因?yàn)橛脩趔w驗(yàn)太差,估計(jì)都要砸鍵盤了。

既然事務(wù)可以并發(fā)操作,這里就有一些問題:一個(gè)事務(wù)在寫數(shù)據(jù)的時(shí)候,另一個(gè)事務(wù)要讀這行數(shù)據(jù),該怎么處理?一個(gè)事務(wù)在寫數(shù)據(jù),另一個(gè)數(shù)據(jù)也要寫這行數(shù)據(jù),又該怎么處理這個(gè)沖突?

這就是并發(fā)事務(wù)所產(chǎn)生的一些問題。具體來說就是:臟讀不可重復(fù)讀幻讀。

概念說明

以下幾個(gè)概念是事務(wù)隔離級別要實(shí)際解決的問題,所以需要搞清楚都是什么意思。

臟讀

臟讀指的是讀到了其他事務(wù)未提交的數(shù)據(jù),未提交意味著這些數(shù)據(jù)可能會(huì)回滾,也就是可能最終不會(huì)存到數(shù)據(jù)庫中,也就是不存在的數(shù)據(jù)。讀到了并一定最終存在的數(shù)據(jù),這就是臟讀。

圖片

臟讀最大的問題就是可能會(huì)讀到不存在的數(shù)據(jù)。比如在上圖中,事務(wù)B的更新數(shù)據(jù)被事務(wù)A讀取,但是事務(wù)B回滾了,更新數(shù)據(jù)全部還原,也就是說事務(wù)A剛剛讀到的數(shù)據(jù)并沒有存在于數(shù)據(jù)庫中。

從宏觀來看,就是事務(wù)A讀出了一條不存在的數(shù)據(jù),這個(gè)問題是很嚴(yán)重的。

不可重復(fù)讀

不可重復(fù)讀指的是在一個(gè)事務(wù)內(nèi),最開始讀到的數(shù)據(jù)和事務(wù)結(jié)束前的任意時(shí)刻讀到的同一批數(shù)據(jù)出現(xiàn)不一致的情況。

圖片

事務(wù) A 多次讀取同一數(shù)據(jù),但事務(wù) B 在事務(wù)A多次讀取的過程中,對數(shù)據(jù)作了更新并提交,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時(shí),結(jié)果 不一致。

幻讀

臟讀、不可重復(fù)讀上面的圖文都很好的理解,對于幻讀網(wǎng)上有很多文章都是這么解釋的

幻讀錯(cuò)誤的理解:說幻讀是 事務(wù)A 執(zhí)行兩次 select 操作得到不同的數(shù)據(jù)集,即 select 1 得到 10 條記錄,select 2 得到 15 條記錄。這其實(shí)并不是幻讀,既然第一次和第二次讀取的不一致,那不還是不可重復(fù)讀嗎,所以這是不可重復(fù)讀的一種。

正確的理解應(yīng)該是

幻讀,并不是說兩次讀取獲取的結(jié)果集不同,幻讀側(cè)重的方面是某一次的 select 操作得到的結(jié)果所表征的數(shù)據(jù)狀態(tài)無法支撐后續(xù)的業(yè)務(wù)操作。更為具體一些:select 某記錄是否存在,不存在,準(zhǔn)備插入此記錄,但執(zhí)行 insert 時(shí)發(fā)現(xiàn)此記錄已存在,無法插入,此時(shí)就發(fā)生了幻讀。

舉例

假設(shè)有張用戶表,這張表的 id 是主鍵。表中一開始有4條數(shù)據(jù)。

圖片

我們再來看下出現(xiàn) 幻讀 的場景

圖片

這里是在RR級別下研究(可重復(fù)讀),因?yàn)?RU / RC 下還會(huì)存在臟讀、不可重復(fù)讀,故我們就以 RR 級別來研究 幻讀,排除其他干擾。

1、事務(wù)A,查詢是否存在 id=5 的記錄,沒有則插入,這是我們期望的正常業(yè)務(wù)邏輯。

2、這個(gè)時(shí)候 事務(wù)B 新增的一條 id=5 的記錄,并提交事務(wù)。

3、事務(wù)A,再去查詢 id=5 的時(shí)候,發(fā)現(xiàn)還是沒有記錄(因?yàn)檫@里是在RR級別下研究(可重復(fù)讀),所以讀到依然沒有數(shù)據(jù))

4、事務(wù)A,插入一條 id=5 的數(shù)據(jù)。

最終 事務(wù)A 提交事務(wù),發(fā)現(xiàn)報(bào)錯(cuò)了。這就很奇怪,查的時(shí)候明明沒有這條記錄,但插入的時(shí)候 卻告訴我 主鍵沖突,這就好像幻覺一樣。這才是所有的幻讀。

不可重復(fù)讀側(cè)重表達(dá) 讀-讀,幻讀則是說 讀-寫,用寫來證實(shí)讀的是鬼影。

事務(wù)的隔離級別

上述所說的"臟讀",“不可重復(fù)讀”,"幻讀"這些問題,其實(shí)就是數(shù)據(jù)庫讀一致性問題,必須由數(shù)據(jù)庫提供的事務(wù)隔離機(jī)制來進(jìn)行解決。

圖片

首先說讀未提交,它是性能最好,也可以說它是最野蠻的方式,因?yàn)樗鼔焊鶅壕筒患渔i,所以根本談不上什么隔離效果,可以理解為沒有隔離。

再來說串行化。串行化就相當(dāng)于上面所說的,處理一個(gè)人請求的時(shí)候,別的人都等著。讀的時(shí)候加共享鎖,也就是其他事務(wù)可以并發(fā)讀,但是不能寫。寫的時(shí)候加排它鎖,其他事務(wù)不能并發(fā)寫也不能并發(fā)讀。

最后說讀提交和可重復(fù)讀。這兩種隔離級別是比較復(fù)雜的,既要允許一定的并發(fā),又想要兼顧的解決問題。MySQL默認(rèn)事務(wù)隔離級別為可重復(fù)讀(RR),oracle默認(rèn)事務(wù)隔離級別為讀已提交(RC),

數(shù)據(jù)庫的事務(wù)隔離越嚴(yán)格,并發(fā)副作用越小,但付出的代價(jià)越大;因?yàn)槭聞?wù)隔離本質(zhì)就是使事務(wù)在一定程度上處于串行狀態(tài),這本身就是和并發(fā)相矛盾的。

同時(shí),不同的應(yīng)用對讀一致性和事務(wù)隔離級別是不一樣的,比如許多應(yīng)用對數(shù)據(jù)的一致性沒那么個(gè)高要求,相反,對并發(fā)有一定要求。

審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    798

    瀏覽量

    26399
收藏 人收藏

    評論

    相關(guān)推薦

    #硬聲創(chuàng)作季 mysql數(shù)據(jù)庫+redis實(shí)戰(zhàn):Mysql隔離級別有哪些

    數(shù)據(jù)庫隔離MySQL
    Mr_haohao
    發(fā)布于 :2022年09月16日 13:14:59

    大數(shù)據(jù)MySQL8.0-155-MySQL事務(wù)-隔離級別-概述#硬聲創(chuàng)作季

    MySQL大數(shù)據(jù)
    電子學(xué)習(xí)
    發(fā)布于 :2023年01月05日 15:46:11

    事務(wù)的四大特性

    事務(wù)和并發(fā)一致性、封鎖、隔離級別
    發(fā)表于 05-09 06:49

    詳解Mysql數(shù)據(jù)庫InnoDB存儲(chǔ)引擎事務(wù)

    關(guān)于Mysql數(shù)據(jù)庫InnoDB存儲(chǔ)引擎事務(wù)的一點(diǎn)理解
    發(fā)表于 05-13 10:11

    Mysql事物級別的定義

    Mysql的事物級別
    發(fā)表于 06-03 15:23

    mysql隔離性測試

    mysql事務(wù)隔離級別測試
    發(fā)表于 09-09 14:27

    MySQL的索引、事務(wù)、視圖介紹

    MySQL--索引、事務(wù)、視圖
    發(fā)表于 06-15 07:05

    MySQL存儲(chǔ)引擎簡析

    索引的情況下才會(huì)起作用。InnoDB 支持事務(wù),且支持四種隔離級別(讀未提交、讀已提交、可重復(fù)讀、串行化),默認(rèn)的為可重復(fù)讀。Myisam??Myisam 的存儲(chǔ)文件有三個(gè),后綴名分別是.frm
    發(fā)表于 09-06 06:07

    MySQL事務(wù)日志

    大家都清楚,日志是 MySQL 數(shù)據(jù)庫的重要組成部分,記錄著數(shù)據(jù)庫運(yùn)行期間各種狀態(tài)信息。MySQL 日志主要包括「錯(cuò)誤日志」、「查詢?nèi)罩尽?、「慢查詢?nèi)罩尽?、「二進(jìn)制日志(binlog)」和 事務(wù)日志
    的頭像 發(fā)表于 11-14 09:58 ?1696次閱讀
    <b class='flag-5'>MySQL</b><b class='flag-5'>事務(wù)</b>日志

    MySQL事務(wù)的四大隔離級別詳解

    之前分析一個(gè)死鎖問題,發(fā)現(xiàn)自己對數(shù)據(jù)庫隔離級別理解還不夠深入,所以趁著這幾天假期,整理一下MySQL事務(wù)的四大隔離
    的頭像 發(fā)表于 11-27 16:07 ?2671次閱讀

    關(guān)于Mysql的20道問題詳解

    1.什么Mysql事務(wù)事務(wù)的四大特性?事務(wù)帶來的什么問題? Mysql事務(wù)
    的頭像 發(fā)表于 10-26 09:56 ?1373次閱讀
    關(guān)于<b class='flag-5'>Mysql</b>的20道問題詳解

    你是否對MySQL數(shù)據(jù)庫中的事務(wù)已經(jīng)有所了解呢?

    你是否對 MySQL 數(shù)據(jù)庫中的事務(wù)已經(jīng)有所了解?看下面這張圖,按照 1~6 的順序依次執(zhí)行,在RR隔離級別下,事務(wù) A 和
    的頭像 發(fā)表于 02-21 17:20 ?603次閱讀

    MYSQL事務(wù)的底層原理詳解

    事務(wù)的實(shí)現(xiàn)機(jī)制上,MySQL 采用的是 WAL:Write-ahead logging,預(yù)寫式日志,機(jī)制來實(shí)現(xiàn)的。
    的頭像 發(fā)表于 11-15 10:10 ?538次閱讀
    <b class='flag-5'>MYSQL</b><b class='flag-5'>事務(wù)</b>的底層原理詳解

    阿里二面:了解MySQL事務(wù)底層原理嗎

    MySQL 是如何來解決臟寫這種問題的?沒錯(cuò),就是鎖。MySQL 在開啟一個(gè)事務(wù)的時(shí)候,他會(huì)將某條記錄和事務(wù)做一個(gè)綁定。這個(gè)其實(shí)和 JVM 鎖是類似的。
    的頭像 發(fā)表于 01-18 16:34 ?307次閱讀
    阿里二面:了解<b class='flag-5'>MySQL</b><b class='flag-5'>事務(wù)</b>底層原理嗎