深入理解MySQL默認事物隔離級別
你想知道 MySQL 的默認事務(wù)隔離級別,這是理解 MySQL 并發(fā)控制、解決臟讀 / 幻讀 / 不可重復(fù)讀等問題的核心知識點。我會從「默認值」「隔離級別分類」「原理驗證」「修改方法」四個維度詳細講解,讓你不僅知其然,更知其所以然。
一、MySQL 默認事務(wù)隔離級別
1. 核心結(jié)論
- InnoDB 引擎(MySQL 默認存儲引擎)的默認事務(wù)隔離級別是:
REPEATABLE READ(可重復(fù)讀); - MySQL 5.1 及以上版本均遵循此規(guī)則,這也是 MySQL 與其他數(shù)據(jù)庫(如 Oracle 默認
READ COMMITTED)的核心區(qū)別之一。
2. 快速驗證(實操命令)
你可以直接在 MySQL 客戶端執(zhí)行以下命令,查看當前默認隔離級別:
-- 查看全局/會話級別的默認隔離級別 SELECT @@GLOBAL.transaction_isolation, @@SESSION.transaction_isolation; -- 舊版本(MySQL 5.6及之前)用這個命令 SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
輸出示例:
| @@GLOBAL.transaction_isolation | @@SESSION.transaction_isolation |
|---|---|
| REPEATABLE-READ | REPEATABLE-READ |
二、事務(wù)隔離級別的完整分類(ACID 中的 I)
SQL 標準定義了 4 種事務(wù)隔離級別,MySQL InnoDB 全部支持,級別從低到高如下(隔離性越強,并發(fā)性能越差):
| 隔離級別 | 臟讀 | 不可重復(fù)讀 | 幻讀 | 核心說明 |
|---|---|---|---|---|
| READ UNCOMMITTED(讀未提交) | ? | ? | ? | 最低級別,能讀取其他事務(wù)未提交的數(shù)據(jù),會導(dǎo)致臟讀 |
| READ COMMITTED(讀已提交) | ? | ? | ? | 只能讀取其他事務(wù)已提交的數(shù)據(jù),解決臟讀,但仍有不可重復(fù)讀 / 幻讀 |
| REPEATABLE READ(可重復(fù)讀) | ? | ? | ? | MySQL 默認,同一事務(wù)內(nèi)多次讀取同一數(shù)據(jù)結(jié)果一致,InnoDB 額外解決了幻讀 |
| SERIALIZABLE(串行化) | ? | ? | ? | 最高級別,事務(wù)串行執(zhí)行,完全解決并發(fā)問題,但性能極差(幾乎不用于生產(chǎn)) |
關(guān)鍵概念解釋(新手必看)
- 臟讀:讀取到其他事務(wù)未提交的修改(比如事務(wù) A 改了數(shù)據(jù)但沒提交,事務(wù) B 讀到了這個未提交的修改,之后 A 回滾,B 讀到的就是 “臟數(shù)據(jù)”);
- 不可重復(fù)讀:同一事務(wù)內(nèi),多次讀取同一數(shù)據(jù),結(jié)果不一致(比如事務(wù) A 讀了數(shù)據(jù),事務(wù) B 修改并提交,A 再讀就變了);
- 幻讀:同一事務(wù)內(nèi),多次執(zhí)行同一查詢,返回的行數(shù)不一致(比如事務(wù) A 查
age=20的用戶有 10 個,事務(wù) B 插入 1 條age=20的記錄并提交,A 再查就變成 11 個,像 “幻覺”)。
三、MySQL 默認級別(REPEATABLE READ)的核心原理
InnoDB 的REPEATABLE READ之所以能同時解決不可重復(fù)讀和幻讀,核心依賴兩個機制:
1. 多版本并發(fā)控制(MVCC)
- 每個事務(wù)啟動時,會生成一個只讀快照(Read View),事務(wù)內(nèi)所有讀取都基于這個快照,不受其他事務(wù)提交的修改影響,因此能保證 “可重復(fù)讀”;
- 快照只對讀操作生效,寫操作(增刪改)仍會鎖定數(shù)據(jù),保證一致性。
2. 間隙鎖(Gap Lock)
- InnoDB 在
REPEATABLE READ級別下,會對索引記錄之間的 “間隙” 加鎖,防止其他事務(wù)插入數(shù)據(jù),從而額外解決了幻讀(這是 MySQL 對 SQL 標準的增強); - 示例:執(zhí)行
SELECT * FROM user WHERE age = 20 FOR UPDATE,InnoDB 會鎖定age=20的記錄,以及age在 19-21 之間的間隙,阻止插入新的age=20的記錄。
四、如何修改事務(wù)隔離級別
1. 臨時修改(當前會話生效,重啟失效)
-- 設(shè)置當前會話的隔離級別為讀已提交 SET SESSION transaction_isolation = 'READ-COMMITTED'; -- 驗證修改結(jié)果 SELECT @@SESSION.transaction_isolation;
2. 永久修改(全局生效,需修改配置文件)
編輯 MySQL 配置文件(my.cnf/my.ini):
[mysqld] # 設(shè)置全局默認隔離級別為讀已提交 transaction-isolation = READ-COMMITTED
重啟 MySQL 服務(wù):
# Linux systemctl restart mysqld # Windows net stop mysql && net start mysql
驗證全局配置:
SELECT @@GLOBAL.transaction_isolation;
3. 按事務(wù)臨時修改(僅當前事務(wù)生效)
-- 開啟事務(wù)前設(shè)置 SET TRANSACTION ISOLATION LEVEL READ COMMITTED; START TRANSACTION; -- 事務(wù)內(nèi)的操作使用讀已提交級別 SELECT * FROM user WHERE age = 20; COMMIT;
五、不同隔離級別的適用場景
| 隔離級別 | 適用場景 | 優(yōu)缺點 |
|---|---|---|
| REPEATABLE READ | 絕大多數(shù)業(yè)務(wù)場景(電商、后臺管理系統(tǒng)等) | 平衡隔離性和并發(fā)性能 |
| READ COMMITTED | 高并發(fā)寫場景(如金融交易)、兼容 Oracle 業(yè)務(wù) | 并發(fā)性能更好,僅解決臟讀 |
| SERIALIZABLE | 數(shù)據(jù)一致性要求極高的場景(如對賬、審計) | 一致性最好,并發(fā)性能極差 |
總結(jié)
- 核心默認值:MySQL InnoDB 引擎的默認事務(wù)隔離級別是
REPEATABLE READ(可重復(fù)讀),這是平衡隔離性和并發(fā)性能的最優(yōu)選擇; - 核心能力:該級別基于 MVCC 解決了不可重復(fù)讀,基于間隙鎖額外解決了幻讀,比 SQL 標準的可重復(fù)讀更強;
- 修改方式:可通過
SET SESSION/GLOBAL臨時 / 全局修改,或修改配置文件永久生效,按需適配業(yè)務(wù)場景。
到此這篇關(guān)于深入理解MySQL默認事物隔離級別的文章就介紹到這了,更多相關(guān)MySQL默認事物隔離級別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
phpstudy無法啟動MySQL服務(wù)的完美解決辦法
學習php當然是要先安裝好運行環(huán)境了,phpstyudy是一個運行php的集成環(huán)境,一鍵安裝對新手很友好,下面這篇文章主要給大家介紹了關(guān)于phpstudy無法啟動MySQL服務(wù)的完美解決辦法,需要的朋友可以參考下2022-06-06

