事務隔離級別是數據庫管理系統(DBMS)中用於控制併發事務之間相互影響的程度。它定義了一個事務在訪問數據時,是否能看到其他事務的中間狀態或未提交的數據。SQL 標準中定義了四種事務隔離。
四種事務隔離級別
- 隔離級別概述
| 隔離級別 | 説明 | 存在問題 |
|---|---|---|
| Read Uncommited | 允許事務讀未提交的事務 | 髒讀 |
| Read commited | 只能讀已提交的事務 | 不可重複讀 |
| Repeatable Read | 同一事務中多次讀取結果(不可重複讀解決) | 幻讀 |
| Serializable | 嚴格的隔離級別,事務完全串行執行 | 無併發問題,性能低 |
- 詳細描述
(1)Read Uncommited(讀取未提交)
- 描述:事務可以讀取其他事務未提交的數據。
- 優點:最低隔離級別,性能較高。
- 可能出現髒讀,即一個事務讀取到另一個未提交事務的修改,導致數據不一致。
- 適用場景:對數據一致性要求不高的場景。
- 示例:
- 事務A修改了數據但是未提交
- 事務B讀取了事務A修改的數據
- 如果事務A回滾了,事務B讀取的數據就無效
(2)Read Commited(讀取已提交)
- 描述:事務只能讀取其他事務以及提交的數據
- 優點:避免了髒讀
- 缺點:可能出現不可重複讀的情況,即同一個事務中多次讀取同一條數據,結果可能不同
- 適用場景:大多數系統的默認隔離級別(如 Oracle 和 SQL Server)。
- 示例:
- 事務A讀取了數據
- 事務B修改了該數據並提交
- 事務A再次讀取數據,發現結果與第一次結果不一致
(3)Repeatable Read(可重複讀)
- 描述:在同一個事務中,多次讀取結果一致,避免了不可重複讀的情況
- 優點:避免了髒讀和不可重複讀問題
- 缺點:可能出現幻讀,即同一事務中執行範圍查詢,其他事務插入了符合條件的數據
- 適用場景:MySQL的默認隔離級別
- 示例:
- 事務A查詢某個條件的數據範圍
- 事務B插入了一條符合的查詢範圍的數據
- 事務A再次查詢,發現結果多了一條數據
(4)Serializable(可串行化)
- 描述:最高隔離級別,事務按順序逐一執行,完全避免併發問題
- 優點:解決了髒讀、不可重複讀和幻讀問題。
- 缺點:性能最低,通常通過鎖機制實現,可能導致大量阻塞。
- 使用場景:對數據一致性要求極高,且併發量較低的場景。
- 實現方式
- 悲觀鎖: 通過加鎖保證事務串行執行。
- MVCC: 通過多版本併發控制(MySQL InnoDB 在 Repeatable Read 中使用)。
MVCC(多版本併發控制器)
-
原理:
- 在可重複讀和讀取已提交隔離級別下,MySQL 的 InnoDB 存儲引擎使用 MVCC 解決併發問題。
- 每條記錄維護多個版本(隱藏的行版本號 trx_id 和回滾指針 undo log)。通過時間戳確保事務只讀到符合當前時間點的數據。
-
特點:
- 讀取操作不加鎖,依賴快照,性能高。
- 適用於 Read Committed 和 Repeatable Read。
MySQL 中的事務隔離級別
在 MySQL 中,可以通過以下命令查看或設置隔離級別:
查看當前隔離級別:
SELECT @@transaction_isolation;
設置隔離級別:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
設置全局隔離級別:
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;