事務隔離級別有四個:1、Read Uncommitted(讀取未提交),允許讀取尚未提交的資料變更,可能造成髒讀、不可重複讀、幻讀。2、Read Committed(讀取已提交),允許讀取並行事務已經提交的資料,可以避免髒讀,但是可能造成不可重複、幻讀。3、Repeatable Read(可重複讀取),對同一欄位多次讀取的結果都是一致。4、Serializable(可序列化)。
本教學操作環境:windows7系統、mysql8版本、Dell G3電腦。
事務是邏輯上的一組操作,要麼全執行,要麼全不執行。
事務最經典栗子也經常被拿出來的栗子就是銀行轉賬了。比如小明要給小紅轉賬1000元,這個轉賬會涉及到兩個關鍵操作:將小明的餘額減1000元,將小紅的餘額減1000元。萬一這兩個操作之間突然出現錯誤,導致小明餘額減少但是小紅餘額沒有增加,這種情況是肯定不允許的。事務就是保證這兩個關鍵操作要麼都成功,要麼都不成功。
在典型的應用程式中,多個事務並行執行,經常會操作相同的資料來完成各自的任務(多個使用者對同一資料進行操作)。並行雖然是必須的,但是可能會帶來以下的問題:
A=20
,事務2也讀取A=20
,事務1修改A=A-1
,事務2也修改A=A-1
,最終結果都是19
,但是事務1的修改記錄丟失了。不可重複讀的重點是修改,幻讀的重點是新增或者刪除。
栗子1(同樣的條件,你讀取過的資料,再次讀取的時候不一樣了):事務1中的A先生讀取自己的工資是1000的操作還沒結束,事務2的B先生就修改了A先生的工資為2000,A先生再次讀取自己工資的時候就變成2000了,這就是不可重複讀。
栗子2(同樣的條件,第1次和第2次讀取出來的記錄條數不一樣):假如某工資表中工資大於3000的有4人,事務1讀取了所有工資大於3000的人,總共查詢到4條記錄,這是事務2又查詢了一條工資大於3000的記錄,事務1再次讀取查詢到的記錄就是5條了,這就是幻讀。
SQL標準定義了四個隔離級別:
隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
讀取未提交 | √ | √ | √ |
讀取已提交 | × | √ | √ |
可重複讀 | × | × | √ |
可序列化 | × | × | × |
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事務隔離級別有哪些的詳細內容,更多請關注TW511.COM其它相關文章!