欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你搞懂MySQL的事務隔離級別

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

一、并行事務會有什么問題?

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

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

臟寫(dirty write)

臟讀(dirty read)

不可重復讀(non-repeatable read)

幻讀(phantom read)

1.1 臟寫

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

舉個例子, 現(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元,默認是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)在有兩個事務,事務A和事務B,事務A是給Tom賬戶余額加100,事務B是給Tom賬戶余額加200。

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

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

1.2 臟讀

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

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

1.3 不可重復讀

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

比如有兩個事務,事務A和事務B,事務A查詢Tom賬戶余額是100,事務B查詢Tom賬戶余額也是100。

接下來,事務A把Tom賬戶余額更新為200,并提交事務。

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

1.4 幻讀

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

最經(jīng)典的是插入的情況。假如現(xiàn)在有兩個事務,事務A和事務B。事務A對某些行的內(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 |
+----+-----------+-----------+--------+

然后,接到上級命令,要把所有賬戶余額大于0的用戶全部標識為富有,啟動事務A完成這項任務,SQL如下:

update bank_balance set wealth = 1 where balance > 0;

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

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

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

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

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

1.5 區(qū)別

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

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

2、不可重復讀主要在于一個事務中多次讀到同一條數(shù)據(jù),但前后讀到的結(jié)果不一樣,這是因為其他事務對數(shù)據(jù)進行修改并提交導致。

3、幻讀則是因為被其他事務插入或者刪除的數(shù)據(jù)影響,一個事務內(nèi)同樣條件的數(shù)據(jù)記錄變多或者變少了。

二、事務隔離級別

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

針對這些問題,SQL定了一套標準,通過 隔離 來規(guī)避,且不同級別的隔離可以規(guī)避不同嚴重程度的事務問題,下面,我們一起看下SQL事務 隔離級別 都有哪些:

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

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

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

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

從1到4,隔離級別依次變高,當然,性能也依次變差。那么這些隔離級別究竟都能防止哪些問題呢?來看一個表格:

只有串行化的隔離級別解決了全部這 3 個問題,其他的 3 個隔離級別都有一定的缺陷。

但,MySQL InnoDB引擎默認的隔離級別是可重復讀(RR) 。

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

非也! 隔離級別越高代價也是越高的 ,且性能也越差。從性能上來說,當然是隔離級別越低越好。

至于隔離級別是RR(可重復讀)下的MySQL怎么避免幻讀問題,InnoDB引擎有它自己的想法,以后單獨抽一講來說啦~

我們再來看一張圖,理解不同隔離級別下讀取到的數(shù)據(jù)是怎么樣的:

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

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

  • 讀提交隔離級別 下,事務 B 修改余額后,只有事務B提交后事務A才能看見,所以事務A中余額R1查詢在提交前,查的值是100,余額R2和余額R3都是在事務B提交后,查詢得到的值都是200。

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

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

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

當B事務要去更新Tom的賬戶余額時,是獲取不到鎖的, 必須等待直至事務A完全提交 。

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

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

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

相關(guān)文章

  • MySQL中如何給一個字段遞增賦值

    MySQL中如何給一個字段遞增賦值

    這篇文章主要介紹了MySQL中如何給一個字段遞增賦值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • MySQL SHOW PROCESSLIST協(xié)助故障診斷全過程

    MySQL SHOW PROCESSLIST協(xié)助故障診斷全過程

    這篇文章主要給大家介紹了關(guān)于MySQL SHOW PROCESSLIST協(xié)助故障診斷的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-02-02
  • phpmyadmin 4+ 訪問慢的解決方法

    phpmyadmin 4+ 訪問慢的解決方法

    很多人用了phpmyadmin4以后的版本發(fā)現(xiàn)速度好像慢了很多,總結(jié)下,提供解決方法。
    2013-11-11
  • Mysql Explain 詳細介紹

    Mysql Explain 詳細介紹

    這篇文章主要介紹了Mysql Explain 詳細介紹的相關(guān)資料,這里對Mysql Explain 的語法,屬性,以及如何使用,做了全面介紹,需要的朋友可以參考下
    2016-11-11
  • MySQL大量臟數(shù)據(jù)如何只保留最新的一條(最新推薦)

    MySQL大量臟數(shù)據(jù)如何只保留最新的一條(最新推薦)

    這篇文章主要介紹了MySQL大量臟數(shù)據(jù),如何只保留最新的一條,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • 總結(jié)MySQL修改最大連接數(shù)的兩個方式

    總結(jié)MySQL修改最大連接數(shù)的兩個方式

    最大連接數(shù)是可以通過mysql進行修改的,mysql數(shù)據(jù)庫修改最大連接數(shù)常用有兩種方法,今天我們分析一下這兩種方法之間的特點和區(qū)別,以便我們能更好的去維護mysql。下面我們來看一下mysql修改最大連接數(shù)的方法,希望文章能夠幫助到各位朋友。
    2016-08-08
  • 如何用SQL命令查看Mysql數(shù)據(jù)庫大小

    如何用SQL命令查看Mysql數(shù)據(jù)庫大小

    本篇文章是對用SQL命令查看Mysql數(shù)據(jù)庫大小的方法進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • Mysql中InnoDB與MyISAM索引差異詳解(最新整理)

    Mysql中InnoDB與MyISAM索引差異詳解(最新整理)

    InnoDB和MyISAM在索引實現(xiàn)和特性上有差異,包括聚集索引、非聚集索引、事務支持、并發(fā)控制、覆蓋索引、主鍵約束、外鍵支持和物理存儲結(jié)構(gòu)等方面,InnoDB更適合事務型應用,而MyISAM適合只讀或讀多寫少的場景,本文介紹Mysql中InnoDB與MyISAM索引差異,感興趣的朋友一起看看吧
    2025-03-03
  • 在MySQL中實現(xiàn)二分查找的詳細教程

    在MySQL中實現(xiàn)二分查找的詳細教程

    這篇文章主要介紹了在MySQL中實現(xiàn)二分查找的詳細教程,來自計算機研究生考試原題,需要的朋友可以參考下
    2015-05-05
  • mysql count(*)分組之后IFNULL無效問題

    mysql count(*)分組之后IFNULL無效問題

    文章總結(jié):作者分享了在解決MySQL中根據(jù)發(fā)票ID和單位統(tǒng)計單位數(shù)量的問題時遇到的困難及解決方法,通過使用IFNULL()函數(shù)和CASEWHEN都無法解決問題,最終作者選擇了嵌套循環(huán)的方法來實現(xiàn)需求,并總結(jié)了經(jīng)驗以供參考
    2024-11-11

最新評論