首頁 > 軟體

mysql資料庫隔離級別詳解

2022-06-16 14:02:28

隔離級別

一、mysql有四個事務隔離級別

每個級別都有字元或數位編號

  1. 讀未提交 READ UNCOMMITTED | 0 : 存在髒讀,不可重複度,幻讀的問題。 
  2. 讀已提交 READ COMMITTED | 1 : 解決髒讀問題,存在不可重複讀,幻讀的問題。
  3. 可重複讀 REPEATABLE READ | 2 : 解決髒讀,不可重複讀的問題,存在幻讀,預設隔離級別,使用MVCC機制實現可重複讀。
  4. 序列化 SERIALIZABLE | 3 : 解決髒讀,不可重複讀,幻讀,可保證事務安全,但完全序列執行,效能最低。

我有記憶方法,先是RU、RC, 記住UC順序,聯想到UC WEB。

二、為什麼預設RR隔離級別?

RR級別作為mysql事務預設隔離級別,是事務完全和效能的折中。SERIALIZABLE級別是悲觀地認為幻讀時刻都會發生,故會自動地隱式地對事務所需資源加排他鎖,其他事務存取此資源會被阻塞等待,故事務是安全的,但需要認值考慮效能。

三、RR隔離級別下手動加鎖解決幻讀理論基礎

InnoDB的行鎖鎖定的是索引,而不是記錄本身。索引對映的記錄存在就加行鎖,如果不存在則會加next-key lock/gap鎖/間隙鎖, 故InnoDB可以實現事務對某記錄的預先佔用。

髒讀、不可重複讀、幻讀 及其解決方法

髒讀

  • 一個事務讀取到另一個事務還沒有提交的資料。解決方法:把事務隔離級別調整到READ COMMITTED。

不可重複讀

  • 一個事務先後讀取同一條記錄,但兩次讀取的資料不同,我們稱之為不可重複讀。解決方法:把事務隔離級別調整到REPEATABLE READ。

幻讀

  • 網上很多文章都說一個事務執行範圍查詢,兩次select得到的條數不同,就叫幻讀,這是錯誤的!!!
  • 幻讀並不是說兩次讀取獲取的結果集不同,幻讀是指某一次select操作得到的結果所表徵的資料狀態無法支援後續的業務操作,具體例子:select某記錄是否存在,不存在,準備插入此記錄,但執行insert時發現此記錄已存在,無法插入,此時就發生了幻讀。
  • 還一種理解思路,就是因為先採用了"快照讀",然後又用了"當前讀",發現結果不同。比如先select是快照讀,然後update、insert等,這時會用到當前讀,發現操作出現未預料結果。

幻讀解決方法

1、把事務隔離級別調整到SERIALIZABLE。2、RR隔離級別下,對select操作手動加行鎖,select ... for update,這也序列化隔離級別下隱式會做的事。

參考文章

幻讀  https://www.jb51.net/article/251790.htm

事務隔離級別命令列操作

1、檢視隔離級別

1)檢視當前對談隔離級別

mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set, 1 warning (0.00 sec)

2)檢視系統隔離級別

mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| READ-UNCOMMITTED      |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

2、設定隔離級別

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

1)設定當前對談

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

2)設定系統

mysql> set global transaction isolation  level read uncommitted;                
Query OK, 0 rows affected (0.00 sec)3、命令列,開始事務時用

操作驗證

自己在命令列去驗證幾種隔離級別下的讀問題。

一、實現髒讀

在不可提交讀, 也就是READ UNCOMMITED情況下,會產生髒讀。

二、操作驗證--實現不可重複讀

在可提交讀, 也就是READ COMMITED情況下,會產生不可重複讀。

三、操作驗證--解決不可重複讀

repeatable read(MySQL預設隔離級別),這時候能解決可重複讀。

右邊事務提交了,修改了age=29,左邊再次查詢,還是28。

四、操作驗證--實現幻讀

repeatable read(MySQL預設隔離級別),這時候還會出現幻讀。

總結

到此這篇關於mysql資料庫隔離級別文章就介紹到這了,更多相關mysql隔離級別內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com