日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL事务的4种隔离级别

發布時間:2024/3/12 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL事务的4种隔离级别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1 簡介
  • 2 什么是數據庫事務?
    • 2.1 事務的四大特性(ACID)
  • 3 并發事務會導致的問題
    • 3.1 本文會使用到的 SQL 語句:
      • 3.1.1 示例表結構
      • 3.1.2 查詢事務的默認隔離級別
      • 3.1.3 設置當前會話的事務隔離級別
  • 4 事務的4種隔離級別和示例演示
    • 4.1 讀未提交
    • 4.2 讀已提交
      • **提交讀的隔離級別會有什么問題呢?**
    • 4.3 可重復讀
      • 那么**可重復讀**真的是否已經解決了幻讀問題呢?畢竟還剩個事務隔離級別呢。
      • 小結
    • 4.4 串行化
  • 相關性
  • 文獻引用

1 簡介

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

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

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

2 什么是數據庫事務?

事務由一個有限的數據庫操作序列組成,這些操作要么全部執行,要么全部不執行,是一個不可分割的工作單位。

例如一個銀行轉賬場景:

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

2.1 事務的四大特性(ACID)

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

3 并發事務會導致的問題

  • 臟讀:事務 A 讀取了事務 B 更新的數據,然后 B 進行回滾操作,那么A讀取的數據就是臟數據
  • 不可重復讀:事務A多次讀取同一數據,事務B在事務A多次讀取的過程中,對數據做了更新并提交,導致事務A多次奪取同一數據時,結果不一致。
  • 幻讀:系統管理員A將數據庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束后發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。

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

3.1 本文會使用到的 SQL 語句:

3.1.1 示例表結構

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 查詢事務的默認隔離級別

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

3.1.3 設置當前會話的事務隔離級別

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

4 事務的4種隔離級別和示例演示

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

4.1 讀未提交

事務A:

事務B:

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

4.2 讀已提交

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

對于提交:當前事務只能讀取其它事務已提交的數據,未提交事務的數據讀取不到。

事務A:

事務B:

由此可以得出結論,隔離級別設置為已提交讀(READ COMMITTED)
時,已經不會出現臟讀問題了,當前事務只能讀取到其他事務提交的數據。但是,站在事務A的角度想想,存在其他問題嗎?

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

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

4.3 可重復讀

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

事務A:

事務B:

到了這一步,可以發現事務隔離級別設置為可重復讀,可以解決幻讀問題。

那么可重復讀真的是否已經解決了幻讀問題呢?畢竟還剩個事務隔離級別呢。

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

但是如果在當前事務中使用了下圖語句進行當前讀:

select * from account for update;

for update是進行當前讀的操作,他會重新從數據庫去加載當前的最新的數據,每執行一次加載一次,如果在此時,另外一個事務為數據庫添加了一個事務,再進行查詢,會發現查詢的數據與之前相比多了或者少了,這也就是幻讀現象。

如果你閱讀到這里,去實操一下,會發現和我說的不一樣,有一種上當的感覺。

其實不是的,這是因為上述都是在標準的可重復讀下的情況,在innodb存儲引擎中對可重復讀進行了改造,為當前讀加上了 Next-key Lock,也就是間隙鎖和行鎖的統稱,行鎖防止了別的事務修改或者刪除,間隙鎖防止了別的事務新增。也就是在進行上面的for update事務中,其他的事務不能對數據進行增刪操作,執行會報錯或者長時間處于等待狀態。

💡 注意:如果A事務如果進行了快照讀,然后通過B事務對數據就行增刪,然后緊接著A事務進行當前讀操作,兩次讀取數據不一致,不能算作幻讀,因為幻讀定義是同一個select語句,快照讀和當前讀的查詢語句是不一樣的.

小結

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

    略,這部分我懶得放圖了,因為結果和上面沒啥差別。

    相關性


    文獻引用


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

    總結

    以上是生活随笔為你收集整理的MySQL事务的4种隔离级别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。