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

一文帶你搞懂MySQL的事務(wù)隔離級(jí)別

 更新時(shí)間:2023年07月03日 08:44:46   作者:看點(diǎn)代碼再上班  
這篇文章主要給大家介紹了MySQL事務(wù)隔離級(jí)別,事務(wù)隔離級(jí)別分別是讀未提交,讀已提交,可重復(fù)讀,串行化,文中有詳細(xì)的圖文介紹,需要的朋友可以參考下

一、并行事務(wù)會(huì)有什么問(wèn)題?

在講事務(wù)隔離級(jí)別之前,我們先想一下,如果有多個(gè)事務(wù)并行執(zhí)行,MySQL數(shù)據(jù)最終會(huì)有什么問(wèn)題?

可以說(shuō),事務(wù)的存在都是為了防止并發(fā)問(wèn)題,我們的MySQL數(shù)據(jù)庫(kù)可以同時(shí)接受多個(gè)client連接,即支持同時(shí)多個(gè)事務(wù)處理,當(dāng)多個(gè)事務(wù)同時(shí)進(jìn)行的時(shí)候,可能會(huì)出現(xiàn)以下等問(wèn)題:

臟寫(dirty write)

臟讀(dirty read)

不可重復(fù)讀(non-repeatable read)

幻讀(phantom read)

1.1 臟寫

臟寫 *(dirty write) *,直白說(shuō)就是兩個(gè)事務(wù)同時(shí)更新一行數(shù)據(jù),事務(wù)A回滾把事務(wù)B的值覆蓋了,實(shí)質(zhì)就是兩個(gè)未提交的事務(wù)互相影響。

舉個(gè)例子, 現(xiàn)在有一張表:

CREATE TABLE `bank_balance` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_name` varchar(45) NOT NULL COMMENT '用戶名',
  `balance` int NOT NULL DEFAULT '0' COMMENT '余額,單位:人民幣分,比如100表示人民幣1元,默認(rèn)是0',
  `wealth` tinyint NOT NULL DEFAULT '0' COMMENT '富有程度,0:貧窮,1:富有',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_bank_balance_user_name` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

表中有一行id=3 且 user_name=Tom的記錄:

mysql> select id,user_name,balance from bank_balance where user_name = 'Tom';
+----+-----------+---------+
| id | user_name | balance |
+----+-----------+---------+
| 3 | Tom       |     100 |
+----+-----------+---------+
1 row in set (0.00 sec)

現(xiàn)在有兩個(gè)事務(wù),事務(wù)A和事務(wù)B,事務(wù)A是給Tom賬戶余額加100,事務(wù)B是給Tom賬戶余額加200。

在①處,事務(wù)A得到的余額是200,事務(wù)B得到的余額是300,如果事務(wù)B是后更新,那么就覆蓋了事務(wù)A的值。

在②處,事務(wù) A 和事務(wù)B都沒(méi)有提交的情況下,它們隨時(shí)都有可能發(fā)生回滾,如上圖這種情況事務(wù) A 發(fā)生了回滾,然后事務(wù)B再提交,那么對(duì)于事務(wù) B 看到的場(chǎng)景而言,就是自己明明更新了,結(jié)果值卻還是舊值,這就是 臟寫 。

1.2 臟讀

*臟讀(dirty read) ****, ***指的是讀到了其他事務(wù)未提交的數(shù)據(jù),未提交意味著可能會(huì)回滾,也就是可能最終不會(huì)持久化到數(shù)據(jù)庫(kù)中。其他事務(wù)讀到了不會(huì)持久化的數(shù)據(jù),這就是臟讀。

比如下圖,如果事務(wù)A在①處發(fā)生回滾,那么事務(wù)B在②處使用的Tom余額值200就是一個(gè)過(guò)期值,這種就是典型的 臟讀現(xiàn)象。

1.3 不可重復(fù)讀

*不可重復(fù)讀(non-repeatable read) *,指的是在同一事務(wù)內(nèi),相同數(shù)據(jù)在不同的時(shí)刻被讀到了不一樣的值,它和臟讀不一樣,臟讀是指讀取到了其他事務(wù)未提交的數(shù)據(jù),而不可重復(fù)讀表示讀到了其他事務(wù)修改并提交后的值。

比如有兩個(gè)事務(wù),事務(wù)A和事務(wù)B,事務(wù)A查詢Tom賬戶余額是100,事務(wù)B查詢Tom賬戶余額也是100。

接下來(lái),事務(wù)A把Tom賬戶余額更新為200,并提交事務(wù)。

當(dāng)事務(wù)B繼續(xù)讀取Tom賬戶余額的時(shí)候,發(fā)現(xiàn)Tom賬戶余額是200了,和之前讀取到的不一致,對(duì)于事務(wù)B而言,這種一個(gè)事務(wù)內(nèi)多次讀取得到不一樣值的現(xiàn)象就稱為不可重復(fù)讀 現(xiàn)象。

1.4 幻讀

*幻讀(phantom read) *,主要是是針對(duì)數(shù)據(jù)插入(INSERT)和刪除(DELETE)操作來(lái)說(shuō)的。

最經(jīng)典的是插入的情況。假如現(xiàn)在有兩個(gè)事務(wù),事務(wù)A和事務(wù)B。事務(wù)A對(duì)某些行的內(nèi)容作了更改,但是還未提交。

比如現(xiàn)在余額表中余額大于0的賬戶有2條,分別是小克和Tom,他們的富有程度都是貧窮:

mysql> select *from bank_balance where balance > 0;
+----+-----------+-----------+--------+
| id | user_name | balance   | wealth |
+----+-----------+-----------+--------+
|  2 | 小克      | 300000000 |      0 |
|  3 | Tom       |       100 |      0 |
+----+-----------+-----------+--------+

然后,接到上級(jí)命令,要把所有賬戶余額大于0的用戶全部標(biāo)識(shí)為富有,啟動(dòng)事務(wù)A完成這項(xiàng)任務(wù),SQL如下:

update bank_balance set wealth = 1 where balance > 0;

SQL語(yǔ)句只是執(zhí)行了,但是未提交。

緊接著,事務(wù)B插入了一條余額大于0的記錄行(富有程度默認(rèn)為貧窮),并且在事務(wù)A提交之前先提交了,SQL如下:

INSERT INTO `bank_balance` (`id`, `user_name`, `balance`) VALUES ('4', 'Eric', '500');

在這之后,如果事務(wù)A再發(fā)起相同條件的查詢,會(huì)發(fā)現(xiàn)剛剛的更改對(duì)于某些數(shù)據(jù)未起作用(有些記錄未被標(biāo)識(shí)為富有),而且數(shù)據(jù)行比原來(lái)還多了!

這對(duì)于事務(wù)A而言,感覺(jué)出現(xiàn)了幻覺(jué)一樣,這就是幻讀現(xiàn)象。

1.5 區(qū)別

讀到這里,可能有些小伙伴就懵了,從臟讀到幻讀,感覺(jué)它們都一樣的呀?其實(shí),它們有實(shí)質(zhì)性的區(qū)別:

1、臟讀重在指一個(gè)事務(wù)讀到了其他事務(wù)未提交的數(shù)據(jù)。

2、不可重復(fù)讀主要在于一個(gè)事務(wù)中多次讀到同一條數(shù)據(jù),但前后讀到的結(jié)果不一樣,這是因?yàn)槠渌聞?wù)對(duì)數(shù)據(jù)進(jìn)行修改并提交導(dǎo)致。

3、幻讀則是因?yàn)楸黄渌聞?wù)插入或者刪除的數(shù)據(jù)影響,一個(gè)事務(wù)內(nèi)同樣條件的數(shù)據(jù)記錄變多或者變少了。

二、事務(wù)隔離級(jí)別

前面已經(jīng)講完并行事務(wù)可能出現(xiàn)的問(wèn)題,具體表象就是臟寫,臟讀,不可重復(fù)讀,幻讀。

針對(duì)這些問(wèn)題,SQL定了一套標(biāo)準(zhǔn),通過(guò) 隔離 來(lái)規(guī)避,且不同級(jí)別的隔離可以規(guī)避不同嚴(yán)重程度的事務(wù)問(wèn)題,下面,我們一起看下SQL事務(wù) 隔離級(jí)別 都有哪些:

  • *讀未提交(READ UNCOMMITTED) *,指一個(gè)事務(wù)還沒(méi)提交,它做的修改就能被其他事務(wù)看到。

  • 讀提 *交(READ COMMITTED) *,一個(gè)事務(wù)做的修改,只有提交之后,其他事務(wù)才能看到。

  • *可重復(fù)讀(REPEATABLE READ) *,在整個(gè)事務(wù)過(guò)程中看到的數(shù)據(jù),自始至終都是一致的。

  • *串行化(SERIALIZABLE) *,每個(gè)讀寫操作都會(huì)加鎖,多個(gè)事務(wù)要訪問(wèn)同一條記錄時(shí),必須要進(jìn)行排隊(duì),優(yōu)先級(jí)低的事務(wù)必須等優(yōu)先級(jí)高的事務(wù)完成以后才能進(jìn)行。

從1到4,隔離級(jí)別依次變高,當(dāng)然,性能也依次變差。那么這些隔離級(jí)別究竟都能防止哪些問(wèn)題呢?來(lái)看一個(gè)表格:

只有串行化的隔離級(jí)別解決了全部這 3 個(gè)問(wèn)題,其他的 3 個(gè)隔離級(jí)別都有一定的缺陷。

但,MySQL InnoDB引擎默認(rèn)的隔離級(jí)別是可重復(fù)讀(RR) 。

為什么MySQL沒(méi)有使用串行化這個(gè)級(jí)別?是不是意味著我們?nèi)粘J褂肕ySQL會(huì)有可能存在幻讀的問(wèn)題?

非也! 隔離級(jí)別越高代價(jià)也是越高的 ,且性能也越差。從性能上來(lái)說(shuō),當(dāng)然是隔離級(jí)別越低越好。

至于隔離級(jí)別是RR(可重復(fù)讀)下的MySQL怎么避免幻讀問(wèn)題,InnoDB引擎有它自己的想法,以后單獨(dú)抽一講來(lái)說(shuō)啦~

我們?cè)賮?lái)看一張圖,理解不同隔離級(jí)別下讀取到的數(shù)據(jù)是怎么樣的:

有兩個(gè)事務(wù),事務(wù)A和事務(wù)B,同時(shí)操作(查詢或者給Tom余額加100),事務(wù)B在事務(wù)A提交前更新了Tom的余額,并且事務(wù)B在事務(wù)A前提交。

  • 讀未提交隔離級(jí)別 下,事務(wù) B 修改余額后,事務(wù) A 能夠馬上看見(jiàn),即使事務(wù)B還未提交,所以事務(wù) A 中余額 R1 查詢的值是 200,余額 R2、R3 也是 200.

  • 讀提交隔離級(jí)別 下,事務(wù) B 修改余額后,只有事務(wù)B提交后事務(wù)A才能看見(jiàn),所以事務(wù)A中余額R1查詢?cè)谔峤磺?,查的值?00,余額R2和余額R3都是在事務(wù)B提交后,查詢得到的值都是200。

  • 可重復(fù)讀隔離級(jí)別 下,事務(wù)A在提交前自始至終查到的值都必須一樣,所以,余額R1、R2都是100,當(dāng)事務(wù)A提交后再查詢(其實(shí)是新事務(wù))就能查到新的值,所以R3是200。

  • 串行化隔離級(jí)別 下,MySQL會(huì)給記錄行以及記錄行之間的'空行'加鎖,如果是A事務(wù)先獲得鎖,那么B事務(wù)必須等到A事務(wù)提交以后才能更新數(shù)據(jù)。

比如上圖,如果事務(wù)A查詢Tom余額的SQL條件是'where user_name = "Tom"', user_name有唯一索引,所以只會(huì)給Tom賬戶這一行數(shù)據(jù)加共享鎖 。

當(dāng)B事務(wù)要去更新Tom的賬戶余額時(shí),是獲取不到鎖的, 必須等待直至事務(wù)A完全提交 。

所以以上R1、R2查詢得到的值都是100(這個(gè)時(shí)候事務(wù)B在排隊(duì)等待),事務(wù)A提交以后, 事務(wù)B就可以更新值并提交了,R3是在事務(wù)B提交之后查詢,所以是200。

好啦,今天就先講到這里啦。

到此這篇關(guān)于一文帶你搞懂MySQL的事務(wù)隔離級(jí)別的文章就介紹到這了,更多相關(guān)MySQL事務(wù)隔離級(jí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySql 空間索引的實(shí)現(xiàn)

    MySql 空間索引的實(shí)現(xiàn)

    MySQL空間索引是一種用于優(yōu)化地理空間數(shù)據(jù)查詢的數(shù)據(jù)結(jié)構(gòu),通過(guò)為幾何數(shù)據(jù)類型創(chuàng)建空間索引,可以高效地對(duì)空間數(shù)據(jù)進(jìn)行查詢和操作,感興趣的可以了解一下
    2024-11-11
  • MySQL運(yùn)行在docker容器性能損失解析

    MySQL運(yùn)行在docker容器性能損失解析

    這篇文章主要為大家介紹了MySQL運(yùn)行在docker容器中的性能損失解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • MySQL中查詢、刪除重復(fù)記錄的方法大全

    MySQL中查詢、刪除重復(fù)記錄的方法大全

    mysql中刪除重復(fù)記錄的方法有很多種,下面這篇文章主要給大家總結(jié)了在MySQL中查詢、刪除重復(fù)記錄的方法大全,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友下面來(lái)一起看看吧。
    2017-06-06
  • linux下mysql 5.1 和 5.7的安裝教程

    linux下mysql 5.1 和 5.7的安裝教程

    下面小編就為大家分享一篇linux下mysql 5.1 和 5.7的安裝教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • Linux下mysql 5.6.17 安裝圖文教程

    Linux下mysql 5.6.17 安裝圖文教程

    這篇文章主要為大家詳細(xì)介紹了Linux下mysql 5.6.17 安裝圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Mysql數(shù)據(jù)庫(kù)從5.6.28版本升到8.0.11版本部署項(xiàng)目時(shí)遇到的問(wèn)題及解決方法

    Mysql數(shù)據(jù)庫(kù)從5.6.28版本升到8.0.11版本部署項(xiàng)目時(shí)遇到的問(wèn)題及解決方法

    這篇文章主要介紹了Mysql數(shù)據(jù)庫(kù)從5.6.28版本升到8.0.11版本過(guò)程中遇到的問(wèn)題及解決方法,解決辦法有三種,每種方法給大家介紹的都很詳細(xì),感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • PHP MySQL的安裝與配置詳解

    PHP MySQL的安裝與配置詳解

    本篇文章給大家介紹php mysql的安裝與配置,首先給大家介紹安裝配置php,接著介紹配置mysql、安裝mysql,本文介紹的非常詳細(xì),需要的朋友可以參考下
    2015-10-10
  • mysql 8.0.25之取巧解決修改密碼報(bào)錯(cuò)的問(wèn)題

    mysql 8.0.25之取巧解決修改密碼報(bào)錯(cuò)的問(wèn)題

    這篇文章主要介紹了mysql8.0.25之取巧解決修改密碼報(bào)錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 在windows10上安裝mysql詳細(xì)圖文教程

    在windows10上安裝mysql詳細(xì)圖文教程

    這篇文章主要介紹了在windows10上安裝mysql詳細(xì)圖文教程,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧
    2016-09-09
  • mysql limit分頁(yè)優(yōu)化詳細(xì)介紹

    mysql limit分頁(yè)優(yōu)化詳細(xì)介紹

    MySQL最常用也最需要優(yōu)化的就是limit,MySQL的limit給分頁(yè)帶來(lái)了極大的方便,但數(shù)據(jù)量一大的時(shí)候,limit的性能就急劇下降,需要的朋友可以參考下
    2016-12-12

最新評(píng)論

商都县| 临清市| 个旧市| 志丹县| 平湖市| 台东市| 同江市| 邓州市| 宁安市| 信阳市| 汽车| 哈巴河县| 常州市| 正阳县| 红桥区| 南澳县| 永修县| 阳朔县| 永新县| 高密市| 游戏| 沅陵县| 丰台区| 瑞安市| 礼泉县| 区。| 喜德县| 准格尔旗| 神池县| 贵德县| 霍林郭勒市| 中西区| 额尔古纳市| 铁岭市| 广西| 读书| 大足县| 九江县| 伊宁市| 上思县| 东乡|