數據庫隔離級別
隔離級別決定了事務之間的可見性規則,直接影響數據庫的并發性能和數據一致性。
SQL 標準定義了 4 種隔離級別,從低到高依次為:讀未提交→讀已提交→可重復讀→串行化。隔離級別越高,對并發問題的解決能力越強,但對性能的消耗也越大(因限制了并發操作)。
一、讀未提交(Read Uncommitted, RU)
定義:一個事務可以讀取另一個事務 未提交 的修改。
解決的問題:無(是最低級別的隔離,幾乎不做任何隔離控制)。
存在的問題:可能出現 臟讀、不可重復讀、幻讀。
示例:
1、事務 B 執行 "修改數據 X 為 100" 但未提交;
2、事務 A 讀取 X=100;
3、事務 B 回滾(X 恢復為 50),事務 A 讀取的 "100" 是無效的(臟讀)。
適用場景:極少使用,僅在對數據一致性要求極低、追求極致并發性能時(如實時監控數據,允許臨時臟數據)。
二、讀已提交(Read Committed, RC)
定義:一個事務只能讀取另一個事務已提交的修改(未提交的修改不可見)。
解決的問題:避免 臟讀(因只能讀已提交的數據)。
存在的問題:可能出現 不可重復讀、幻讀。
示例:
1、事務 A 第一次讀取 X=50;
2、事務 B 修改 X 為 100 并提交;
3、事務 A 第二次讀取 X=100(與第一次不一致,不可重復讀)。
實現原理:通過 "行級鎖" 或 "快照讀" 實現(如 Oracle 默認用快照讀:每個事務讀取數據時,獲取該數據的 "已提交版本")。
適用場景:大多數互聯網業務(如電商訂單、支付場景),平衡了一致性和并發性能,是 Oracle、SQL Server 的默認隔離級別。
三、可重復讀(Repeatable Read, RR)
定義:一個事務在執行期間,多次讀取同一批數據的結果始終一致(不受其他事務提交的修改影響)。
解決的問題:避免臟讀、不可重復讀。
存在的問題:可能出現幻讀(因無法限制其他事務新增 / 刪除符合條件的記錄)。
示例:
1、事務 A 第一次查詢 "年齡> 18 的用戶",返回 10 條;
2、事務 B 新增 1 條 "年齡 = 20" 的用戶并提交;
3、事務 A 再次查詢 "年齡> 18 的用戶",返回 11 條(記錄數變化,幻讀)。
實現原理:通過 "多版本并發控制(MVCC)" 實現(每個事務啟動時生成一個 "數據快照",后續讀取基于該快照,不受其他事務提交的修改影響)。
特殊說明:MySQL 的 InnoDB 引擎對 RR 做了增強,通過 "間隙鎖(Gap Lock)" 避免了部分幻讀場景(但并非完全解決,極端情況仍可能出現),因此 InnoDB 的 RR 實際隔離性略高于標準定義。
適用場景:對數據一致性要求較高的業務(如金融交易、庫存管理),是 MySQL InnoDB 的默認隔離級別。
四、串行化(Serializable, S)
定義:所有事務 "串行執行"(即一個接一個執行,不允許并發操作同一批數據)。
解決的問題:避免 臟讀、不可重復讀、幻讀(是最高級別的隔離,完全保證數據一致性)。
存在的問題:并發性能極差(因本質是 "單線程" 執行,會導致大量事務等待)。
實現原理:通過 "表級鎖" 或 "范圍鎖" 強制事務串行化(如事務 A 操作某范圍數據時,其他事務對該范圍的讀寫均被阻塞)。
示例:
1、事務 A 執行 "查詢年齡> 18 的用戶" 并準備修改;
2、事務 B 嘗試新增 "年齡 = 20" 的用戶時,會被阻塞,直到事務 A 完成并釋放鎖;
3、因此事務 A 兩次查詢的結果完全一致,無幻讀。
適用場景:僅在對數據一致性要求極高、并發量極低的場景(如銀行核心交易的對賬操作,不允許任何并發不一致)。
隔離級別對比
| 隔離級別 | 臟讀 | 不可重復讀 | 幻讀 | 并發性能 | 典型數據庫默認值 |
|---|---|---|---|---|---|
| 讀未提交(RU) | 可能 | 可能 | 可能 | 最高 | 幾乎無數據庫默認 |
| 讀已提交(RC) | 不可能 | 可能 | 可能 | 較高 | Oracle、SQL Server |
| 可重復讀(RR) | 不可能 | 不可能 | 可能 | 中等 | MySQL InnoDB |
| 串行化(S) | 不可能 | 不可能 | 不可能 | 最低 | 無數據庫默認 |
不可重復讀與臟讀的區別
- 臟讀(Dirty Read):讀取到其他事務 未提交 的數據;
- 不可重復讀(Non-repeatable Read):讀取到其他事務 已提交 的 修改。
不可重復讀與幻讀的區別
- 不可重復讀(Non-repeatable Read):針對 已存在 數據的 修改;
- 幻讀(Phantom Read):針對 新增或刪除 的數據行。
人活一世,謀生之道,立世之途,為人之智,盡在書中。-- 煙沙九洲
浙公網安備 33010602011771號