交易隔離等級有四個: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影片教學# ##】###以上是mysql事務隔離等級有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!