最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解MySQL事務(wù)的4種隔離級別

 更新時(shí)間:2022年04月20日 09:44:44   作者:一年春又來  
本文主要介紹了MySQL事務(wù)的4種隔離級別,事務(wù)的4種隔離級別分別是讀未提交,讀已提交,可重復(fù)讀和串行化,具有一定的參考價(jià)值,感興趣的可以了解一下

1 簡介

事務(wù)的4種隔離級別分別是讀未提交(Read Uncommitted)、讀已提交(Read Committed)、 可重復(fù)讀(Repeatable Read)和串行化(Serializable)。

首先,在了解這4種隔離級別前就必須先要了解其前提,也就是事務(wù),本文簡單介紹一下關(guān)于事務(wù)。

之后,我們也要理解這4種隔離級別產(chǎn)生的原因和場景展現(xiàn)以及4種隔離級別是如何解決問題的。

2 什么是數(shù)據(jù)庫事務(wù)?

事務(wù)由一個(gè)有限的數(shù)據(jù)庫操作序列組成,這些操作要么全部執(zhí)行,要么全部不執(zhí)行,是一個(gè)不可分割的工作單位。

例如一個(gè)銀行轉(zhuǎn)賬場景:

A轉(zhuǎn)賬B 100元,A的賬號扣除100元,B的賬號加上100塊。假如中間出現(xiàn)任何異常,例如,在A的賬號扣100元時(shí),銀行癱瘓,B的賬號余額沒有發(fā)生變化。這時(shí)候就需要事務(wù)來保證將A的錢還回去。

2.1 事務(wù)的四大特性(ACID)

  • 原子性:事務(wù)作為一個(gè)整體被執(zhí)行,包含在其中的對數(shù)據(jù)庫的操作要么全部都執(zhí)行,要么都不執(zhí)行。
  • 一致性:指在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)不會被破壞,假如A賬戶給B賬戶轉(zhuǎn)10塊錢,不管成功與否,A和B的總金額是不變的。
  • 隔離性:多個(gè)事務(wù)并發(fā)訪問時(shí),事務(wù)之間是相互隔離的,一個(gè)事務(wù)不應(yīng)該被其他事務(wù)干擾,多個(gè)并發(fā)事務(wù)之間要相互隔離。
  • 持久性:表示事務(wù)完成提交后,該事務(wù)對數(shù)據(jù)庫所作的操作更改,將持久地保存在數(shù)據(jù)庫之中。

3 并發(fā)事務(wù)會導(dǎo)致的問題

  • 臟讀:事務(wù) A 讀取了事務(wù) B 更新的數(shù)據(jù),然后 B 進(jìn)行回滾操作,那么A讀取的數(shù)據(jù)就是臟數(shù)據(jù)
  • 不可重復(fù)讀:事務(wù)A多次讀取同一數(shù)據(jù),事務(wù)B在事務(wù)A多次讀取的過程中,對數(shù)據(jù)做了更新并提交,導(dǎo)致事務(wù)A多次奪取同一數(shù)據(jù)時(shí),結(jié)果不一致。
  • 幻讀:系統(tǒng)管理員A將數(shù)據(jù)庫中所有學(xué)生的成績從具體分?jǐn)?shù)改為ABCDE等級,但是系統(tǒng)管理員B就在這個(gè)時(shí)候插入了一條具體分?jǐn)?shù)的記錄,當(dāng)系統(tǒng)管理員A改結(jié)束后發(fā)現(xiàn)還有一條記錄沒有改過來,就好像發(fā)生了幻覺一樣,這就叫幻讀。

?? 不可重復(fù)讀的和幻讀很容易混淆,不可重復(fù)讀側(cè)重于修改,幻讀側(cè)重于新增或刪除。解決不可重復(fù)讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表。

3.1 本文會使用到的 SQL 語句

3.1.1 示例表結(jié)構(gòu)

CREATE TABLE `account` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `balance` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `un_name_idx` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3.1.2 查詢事務(wù)的默認(rèn)隔離級別

mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |
+-------------------------+
1 row in set (0.01 sec)

3.1.3 設(shè)置當(dāng)前會話的事務(wù)隔離級別

mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)

4 事務(wù)的4種隔離級別和示例演示

事務(wù)隔離級別臟讀不可重復(fù)讀幻讀
讀未提交(read-uncommitted)
不可重復(fù)讀(read-committed)又叫讀已提交
可重復(fù)讀(repeatable-read)
串行化(serializable)

4.1 讀未提交

事務(wù)A:

Untitled

事務(wù)B:

Untitled

?? 讀未提交是隔離級別最低的,會造成臟讀。

4.2 讀已提交

為了避免臟讀,數(shù)據(jù)庫有了比讀未提交更高的隔離級別,即讀已提交。

對于提交:當(dāng)前事務(wù)只能讀取其它事務(wù)已提交的數(shù)據(jù),未提交事務(wù)的數(shù)據(jù)讀取不到。

事務(wù)A:

Untitled

事務(wù)B:

Untitled

由此可以得出結(jié)論,隔離級別設(shè)置為已提交讀(READ COMMITTED)
時(shí),已經(jīng)不會出現(xiàn)臟讀問題了,當(dāng)前事務(wù)只能讀取到其他事務(wù)提交的數(shù)據(jù)。但是,站在事務(wù)A的角度想想,存在其他問題嗎?

提交讀的隔離級別會有什么問題呢?

在同一個(gè)事務(wù)A里,相同的查詢sql,讀取同一條記錄(id=1),讀到的結(jié)果是不一樣的,即不可重復(fù)讀。所以,隔離級別設(shè)置為read committed的時(shí)候,還會存在不可重復(fù)讀的并發(fā)問題。

4.3 可重復(fù)讀

為了避免不可重復(fù)讀的并發(fā)問題,我們將隔離級別設(shè)置為可重復(fù)讀(REPEATABLEE READ),重復(fù)一下之前的操作。

事務(wù)A:

Untitled

事務(wù)B:

Untitled

到了這一步,可以發(fā)現(xiàn)事務(wù)隔離級別設(shè)置為可重復(fù)讀,可以解決幻讀問題。

那么可重復(fù)讀真的是否已經(jīng)解決了幻讀問題呢?畢竟還剩個(gè)事務(wù)隔離級別呢。

RR隔離級別下,手動(dòng)啟動(dòng)一個(gè)事務(wù),進(jìn)行select操作,他會生成一個(gè)快照,可以理解為將當(dāng)前數(shù)據(jù)庫的數(shù)據(jù)復(fù)制一份,在當(dāng)前事務(wù)中,之后不管進(jìn)行多少次select查詢,都是在模板中去取數(shù)據(jù),所以不管數(shù)據(jù)庫中是否對數(shù)據(jù)進(jìn)行了改變,都不會影響當(dāng)前事務(wù)數(shù)據(jù)的讀取,從而避免了幻讀。這種普通的 select 操作,稱為快照讀。

但是如果在當(dāng)前事務(wù)中使用了下圖語句進(jìn)行當(dāng)前讀:

select * from account for update;

for update是進(jìn)行當(dāng)前讀的操作,他會重新從數(shù)據(jù)庫去加載當(dāng)前的最新的數(shù)據(jù),每執(zhí)行一次加載一次,如果在此時(shí),另外一個(gè)事務(wù)為數(shù)據(jù)庫添加了一個(gè)事務(wù),再進(jìn)行查詢,會發(fā)現(xiàn)查詢的數(shù)據(jù)與之前相比多了或者少了,這也就是幻讀現(xiàn)象。

如果你閱讀到這里,去實(shí)操一下,會發(fā)現(xiàn)和我說的不一樣,有一種上當(dāng)?shù)母杏X。

其實(shí)不是的,這是因?yàn)樯鲜龆际窃跇?biāo)準(zhǔn)的可重復(fù)讀下的情況,在innodb存儲引擎中對可重復(fù)讀進(jìn)行了改造,為當(dāng)前讀加上了 Next-key Lock,也就是間隙鎖和行鎖的統(tǒng)稱,行鎖防止了別的事務(wù)修改或者刪除,間隙鎖防止了別的事務(wù)新增。也就是在進(jìn)行上面的for update事務(wù)中,其他的事務(wù)不能對數(shù)據(jù)進(jìn)行增刪操作,執(zhí)行會報(bào)錯(cuò)或者長時(shí)間處于等待狀態(tài)。

?? 注意:如果A事務(wù)如果進(jìn)行了快照讀,然后通過B事務(wù)對數(shù)據(jù)就行增刪,然后緊接著A事務(wù)進(jìn)行當(dāng)前讀操作,兩次讀取數(shù)據(jù)不一致,不能算作幻讀,因?yàn)榛米x定義是同一個(gè)select語句,快照讀和當(dāng)前讀的查詢語句是不一樣的.

小結(jié)

  • 數(shù)據(jù)庫的并發(fā)問題有:臟讀、不可重復(fù)讀和幻讀;
  • 事務(wù)隔離級別依次為:讀未提交、讀已提交、可重復(fù)讀和串行化;
  • 在標(biāo)準(zhǔn)的RR下并沒有徹底解決幻讀,但是在Mysql的innodb引擎中徹底解決了;
  • innodb通過 Next-Key lock解決的幻讀問題,其實(shí)也就是阻塞串行化了;
  • 不能把快照讀和當(dāng)前讀在一個(gè)事務(wù)中進(jìn)行比較是否出現(xiàn)幻讀,兩者不是同一個(gè)select,不滿足幻讀的官方定義。

4.4 串行化

略,這部分我懶得放圖了,因?yàn)榻Y(jié)果和上面沒啥差別。

文獻(xiàn)引用

一文徹底讀懂MySQL事務(wù)的四大隔離級別 - Jay_huaxiao - 博客園

到此這篇關(guān)于深入理解MySQL事務(wù)的4種隔離級別的文章就介紹到這了,更多相關(guān)MySQL事務(wù)隔離內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mysql 取字段值逗號第一個(gè)數(shù)據(jù)的查詢語句

    Mysql 取字段值逗號第一個(gè)數(shù)據(jù)的查詢語句

    Mysql 取字段值逗號第一個(gè)數(shù)據(jù),在某些情況下還是比較實(shí)用的,主要使用到了left函數(shù)及其他等等,感興趣的朋友可以參考下
    2013-10-10
  • MYSQL數(shù)據(jù)庫主從同步設(shè)置的實(shí)現(xiàn)步驟

    MYSQL數(shù)據(jù)庫主從同步設(shè)置的實(shí)現(xiàn)步驟

    本文主要介紹了MYSQL數(shù)據(jù)庫主從同步設(shè)置的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Mysql中強(qiáng)制索引的具體使用

    Mysql中強(qiáng)制索引的具體使用

    Mysql強(qiáng)制索引可以通過強(qiáng)制使用某些列的索引來提高查詢的性能,本文就來介紹一下Mysql中強(qiáng)制索引的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • Mysql中的日期時(shí)間函數(shù)小結(jié)

    Mysql中的日期時(shí)間函數(shù)小結(jié)

    本文主要介紹了Mysql中的日期時(shí)間函數(shù)小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • mysql實(shí)現(xiàn)connect by start with方式

    mysql實(shí)現(xiàn)connect by start with方式

    本文介紹了MySQL中實(shí)現(xiàn)層級查詢的幾種方法,并分享了一種使用變量循環(huán)賦值的方式,通過實(shí)驗(yàn)驗(yàn)證了該方法的有效性
    2024-12-12
  • MySQL中MRR如何優(yōu)化范圍查詢

    MySQL中MRR如何優(yōu)化范圍查詢

    MySQL提供了多種優(yōu)化技術(shù)以提高查詢性能,其中,MRR(Multi-Range Read)優(yōu)化是一種重要的查詢優(yōu)化技術(shù),尤其在處理包含多個(gè)范圍條件的查詢時(shí),能夠顯著提升查詢效率,本文給大家介紹了MySQL中MRR(多范圍讀取)如何優(yōu)化范圍查詢,需要的朋友可以參考下
    2024-10-10
  • MySQL查看event執(zhí)行記錄的實(shí)現(xiàn)

    MySQL查看event執(zhí)行記錄的實(shí)現(xiàn)

    在使用EVENT的過程中,我們可能會需要查看EVENT的執(zhí)行記錄,以便了解它們是否按預(yù)期執(zhí)行,本文就來介紹一下MySQL查看event執(zhí)行記錄的實(shí)現(xiàn),感興趣的可以了解一下
    2023-11-11
  • MySQL的分區(qū)表使用場景及示例小結(jié)

    MySQL的分區(qū)表使用場景及示例小結(jié)

    MySQL的分區(qū)表功能在某些場景下可以顯著提高查詢效率,本文主要介紹了MySQL的分區(qū)表使用場景及示例小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • MySQL高速緩存啟動(dòng)方法及參數(shù)詳解(query_cache_size)

    MySQL高速緩存啟動(dòng)方法及參數(shù)詳解(query_cache_size)

    這篇文章主要介紹了MySQL高速緩存啟動(dòng)方法及參數(shù)詳解(query_cache_size),需要的朋友可以參考下
    2014-12-12
  • MySQL 從全庫備份中恢復(fù)指定的表和庫示例

    MySQL 從全庫備份中恢復(fù)指定的表和庫示例

    這篇文章主要介紹了MySQL 從全庫備份中恢復(fù)指定的表和庫示例的相關(guān)資料,這里提供了相應(yīng)的方法,來實(shí)現(xiàn)恢復(fù)指定的表和庫數(shù)據(jù),需要的朋友可以參考下
    2016-11-11

最新評論

辽源市| 襄垣县| 舒城县| 济宁市| 偏关县| 赣州市| 株洲市| 临澧县| 松潘县| 山阳县| 竹北市| 连云港市| 万载县| 成都市| 柘城县| 漳浦县| 平邑县| 汤阴县| 武宁县| 开平市| 衡阳市| 罗城| 三江| 丰原市| 神农架林区| 当阳市| 山东| 隆昌县| 山东省| 泸州市| 大同县| 徐闻县| 定日县| 平湖市| 平塘县| 鄯善县| 鹤庆县| 冀州市| 六盘水市| 伊宁县| 长白|