首頁  >  文章  >  資料庫  >  mysql事務隔離等級有哪些

mysql事務隔離等級有哪些

青灯夜游
青灯夜游原創
2023-01-04 16:37:5915817瀏覽

交易隔離等級有四個:1、Read Uncommitted(讀取未提交),允許讀取尚未提交的資料變更,可能造成髒讀、無法重複讀取、幻讀。 2、Read Committed(讀取已提交),允許讀取並發事務已經提交的數據,可以避免髒讀,但是可能造成不可重複、幻讀。 3、Repeatable Read(可重複讀取),對相同欄位多次讀取的結果都是一致。 4、Serializable(可串行化)。

mysql事務隔離等級有哪些

本教學操作環境:windows7系統、mysql8版本、Dell G3電腦。

一、什麼是事務?

事務是邏輯上的一組操作,要麼全執行,要麼全不執行。

事務最經典栗子也常被拿出來的栗子就是銀行轉帳了。例如小明要給小紅轉帳1000元,這個轉帳會涉及到兩個關鍵操作:將小明的餘額減1000元,將小紅的餘額減1000元。萬一這兩個操作之間突然出現錯誤,導緻小明餘額減少但是小紅餘額沒有增加,這種情況是肯定不允許的。事務就是要保證這兩個關鍵操作要嘛都成功,要嘛都不成功。

二、事務的特性(ACID)

  • **原子性:* *事務最小的執行單位,不允許分割。事務的原子性確保動作要麼全部執行,要麼全部不執行。
  • **一致性:**執行交易的前後,資料保持一致。例如轉帳的業務中,無論事務是否成功,轉帳者和收款人的總額應是不變的。
  • **隔離性:**並發存取資料庫時,一個使用者的事務不應該被其他事務所影響,各並發交易之間資料庫是獨立的。
  • **持久性:**一個事務被提交後,它對資料庫中資料的改變是持久的,即使資料庫發生故障也不應該對其有影響。

三、並發交易帶來的問題

在典型的應用程式中,多個交易並發運行,經常會操作相同的資料來完成各自的任務(多個使用者對相同資料進​​行操作)。並發雖然是必須的,但是可能會帶來以下的問題:

  • **髒讀(Dirty read):**當一個事務正在存取資料並且對其進行了修改,但是還沒提交事務,這時另外一個事務也訪問了這個數據,然後使用了這個數據,因為這個數據的修改還沒提交到數據庫,所以另外一個事務讀取的數據就是「髒數據 ”,這種行為就是“髒讀”,依據“髒資料”所做的操作可能是會出現問題的。
  • 修改遺失(Lost of modify):是指一個事務讀取一個數據時,另外一個數據也訪問了該數據,那麼在第一個事務修改了這個數據之後,第二個事務也修改了這個數據。這樣第一個事務內的修改結果就被遺失,這種情況就被稱為修改丟失。例如:事務1讀取表中資料A=20,事務2也讀取A=20,事務1修改A=A-1,事務2也修改A=A-1,最終結果都是19,但是事務1的修改記錄遺失了。
  • 不可重複讀(Unrepeatableread):指在一個事務內多次讀取同一數據,在這個事務還沒結束時,另外一個事務也訪問了這個數據並對這個資料進行了修改,那麼就可能造成第一個交易兩次讀取的資料不一致,這種情況就被稱為不可重複讀。
  • 幻讀(Phantom read):幻讀與不可重複讀類似,幻讀是指一個事務讀取了幾行數據,這個事務還沒結束,接著另外一個事務插入了一些數據,在隨後的查詢中,第一個事務讀取到的數據就會比原本讀取到的多,就好像發生了幻覺一樣,所以稱為幻讀

無法重複讀取和幻讀差異:

不可重複讀取的重點是修改,幻讀的重點是新增或刪除。

栗子1(同樣的條件,你讀取過的數據,再次讀取的時候不一樣了):事務1中的A先生讀取自己的工資是1000的操作還沒結束,事務2的B先生就修改了A先生的薪水為2000,A先生再讀取自己薪水的時候就變成2000了,這就是不可重複讀。

栗子2(同樣的條件,第1次和第2次讀取出來的記錄條數不一樣):假如某工資表中工資大於3000的有4人,事務1讀取了所有薪水大於3000的人,總共查詢到4筆記錄,這是事務2又查詢了一筆薪水大於3000的記錄,事務1再次讀取查詢到的記錄就是5筆了,這就是幻讀。

四、交易隔離等級

SQL標準定義了四個隔離等級:

  • **讀取未提交(READ-UNCOMMITTED):**最低的隔離級別,允許讀取尚未提交的資料變更,可能造成髒讀、不可重複讀取、幻讀。
  • **讀取已提交(READ-COMMITTED):**允許讀取並發事務已經提交的數據,可以避免髒讀,但是可能造成不可重複、幻讀。
  • **可重複讀取(REPEATABLE-READ):**對相同欄位多次讀取的結果都是一致的,除非本身事務修改,可以避免髒讀和不可重複讀,但是可能造成幻讀。
  • **可串行化(SERIALIZABLE):**最高的隔離級別,完全服從ACID的隔離級別,所有的事務依次執行,可以避免髒讀、不可重複讀、幻讀。
##√#讀取已提交×√√可重複讀取× ×
隔離等級 髒讀 無法重複讀取 幻讀
讀取未提交
###√############可串列化######×######×########################################################## ×############

MySQL InnoDB儲存引擎預設的交易隔離等級是可重複讀取(REPEATABLE-READ),可以透過指令select @@tx_isolation;語句來查看,MySQL 8.0 該語句改為SELECT @@transaction_isolation;

mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+

MySQL InnoDB儲存引擎的可重複讀取並不能避免幻讀,需要應用使用加鎖讀來保證,這加鎖讀使用到的機制就是Next-Key Locks

因為隔離等級越低,交易請求的鎖定越少,所以大部分資料庫系統的隔離等級都是讀取已提交(READ-COMMITTED)InnoDB 儲存引擎預設使用REPEATABLE-READ(可重讀) 並不會有任何效能損失。

InnoDB儲存引擎在分散式交易的情況下一般會用到可串行化隔離等級。

? 拓展一下(以下內容摘自《MySQL 技術內幕:InnoDB 儲存引擎(第2 版)》7.7 章):

InnoDB儲存引擎提供了對XA事務的支持,並透過XA事務來支援分散式事務的實現。分散式事務指的是允許多個獨立的事務資源參與到一個全域的事務。事務資源通常是關係型資料庫系統,但也可以是其他類型的資源。全域事務要求在其中的所有參與的事務要么都提交,要么都回滾,這對事務的原有ACID要求又有了提高。另外,在使用分散式事務時,InnoDB 儲存引擎的事務隔離等級必須設定為 SERIALIZABLE。

四、實際狀況示範

#MySQL命令列的預設組態中交易都是自動提交的,即執行SQL語句就會馬上執行COMMIT操作。可以用指令START TRANSACTION開始一個交易。

我們可以透過下面指令來設定交易隔離等級。

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

我們再來看看我們在實際操作中使用到的一些同時控制語句:

  • START TRANSACTION | BEGIN :顯示的開啟一個交易。
  • COMMIT:提交事務,使得資料庫所做的所有修改成為永久性。
  • ROLLBACK:回滾到結束使用者的事務,並撤銷正在進行的所有未提交的修改。

(髒讀)讀取未提交

#(避免髒讀)讀取已提交

無法重複讀取

還是剛才上面的讀已提交的圖,雖然避免了讀未提交,但是卻出現了,一個事務還沒結束,就發生了不可重複讀問題。

    可重複讀取
  • #[外鏈圖片轉存失敗,來源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ysjbfC4b-1651149978452)(https://qtspace.cn/contentimg/81.jpg)]
  • 幻讀
示範幻讀出現的情況

sql 腳本1 在第一次查詢薪資為500 的記錄時只有一條,sql 腳本2 插入了一筆薪資為500 的記錄,提交之後;sql 腳本1 在同一筆交易中再次使用目前讀取查詢發現出現了兩筆薪資為500 的記錄這種就是幻讀。

幻讀和不可重複讀有些相似之處 ,但是不可重複讀的重點是修改,幻讀的重點在於新增或刪除。 解決幻讀的方法

######將交易隔離等級調整為 ###SERIALIZABLE###。 ######在可重複讀取的交易層級下,為事務操作的這張表新增表格鎖定。 ######在可重複讀取的交易層級下,為事務操作的這張表新增 ###Next-Key Locks###。 ############說明:###Next-Key Locks### 相當於行鎖間隙鎖定#########【相關推薦:###mysql影片教學# ##】###

以上是mysql事務隔離等級有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn