MySQL 透過四種事務隔離級別解決並發一致性問題,每級別對「髒讀、不可重複讀、幻讀」的防護程度不同。理解這四個級別,能幫助你在效能與一致性之間做出正確取捨。
| 隔離級別 | 髒讀 | 不可重複讀 | 幻讀 | 鎖開銷 |
|---|---|---|---|---|
| Read Uncommitted(讀未提交) | ✅ 可能 | ✅ 可能 | ✅ 可能 | 最低 |
| Read Committed(讀已提交) | ❌ 防止 | ✅ 可能 | ✅ 可能 | 低 |
| Repeatable Read(可重複讀) MySQL 預設 | ❌ 防止 | ❌ 防止 | ✅ 可能(InnoDB 用 Next-Key Lock 緩解) | 中 |
| Serializable(可串行化) | ❌ 防止 | ❌ 防止 | ❌ 完全防止 | 最高(易超時、鎖競爭) |
事務可讀取其他事務「尚未提交」的修改。極度輕量,但資料極不穩定,幾乎不用於生產環境。
只能讀到已提交的資料,解決髒讀。但同一事務多次查詢同一行,若被其他事務修改並提交,會看到不同值(不可重複讀)。Oracle、PostgreSQL 預設即此級別。
事務啟動時建立一致性快照,同一事務內多次查詢同一行,結果永遠一致(防止不可重複讀)。InnoDB 透過 Next-Key Lock(記錄鎖 + 間隙鎖) 大幅降低幻讀機率,但極端情況下仍可能出現幻讀。
最高級別,強制事務串行執行。InnoDB 在每條讀取的記錄上加共享鎖,寫入加排他鎖,徹底消除幻讀,但並發效能極差,極易產生大量鎖等待與超時。
-- 查看當前隔離級別
SELECT @@transaction_isolation;
-- 設定當前會話隔離級別
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 設定全域預設(需重啟或修改 my.cnf)
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEABLE READ;
記住:隔離級別越高,鎖衝突越多,吞吐量越低。實際專案請配合 SHOW ENGINE INNODB STATUS 觀察鎖等待,再決定是否調高級別。