資料庫事務的隔離級別決定了併發環境下資料的一致性與效能權衡。MySQL 支援四種隔離級別,本文將詳細解析各級別特性、預設值,並透過實際 Session 互動演示 REPEATABLE READ 的行為表現。
| 隔離級別 | 髒讀 | 不可重複讀 | 幻讀 | 說明 |
|---|---|---|---|---|
| READ UNCOMMITTED | 可能 | 可能 | 可能 | 讀取未提交資料,效能最高但一致性最差 |
| READ COMMITTED | 不可 | 可能 | 可能 | Oracle 預設級別,僅能讀取已提交資料 |
| REPEATABLE READ | 不可 | 不可 | 可能 | MySQL InnoDB 預設級別,同一事務多次讀取結果一致 |
| SERIALIZABLE | 不可 | 不可 | 不可 | 最高級別,強制串行執行,效能最低 |
(mysql@localhost) [fandb]> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
建立測試表 per1(id, name),初始資料:(1, 'fan')
(mysql@localhost) [fandb]> begin;
(mysql@localhost) [fandb]> update per1 set name='fan1' where id=1;
(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
| 1 | fan1 |
+----+------+
(mysql@localhost) [fandb]> begin;
(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
| 1 | fan | -- 仍看到舊值,未讀到 A 的未提交修改
+----+------+
(mysql@localhost) [fandb]> commit;
(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
| 1 | fan | -- 仍看到舊值!可重複讀特性:同一事務內快照固定
+----+------+
(mysql@localhost) [fandb]> commit;
(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
| 1 | fan1 | -- 新事務才能看到最新提交值
+----+------+
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;理解隔離級別對設計高併發系統至關重要,建議在開發階段即釐清業務對一致性與效能的具體要求。