目录
[一、事务隔离性的背景:并发 vs 准确,鱼与熊掌如何兼得?](#一、事务隔离性的背景:并发 vs 准确,鱼与熊掌如何兼得?)
[1. 脏读(Dirty Read)](#1. 脏读(Dirty Read))
[2. 不可重复读(Non-Repeatable Read)](#2. 不可重复读(Non-Repeatable Read))
[3. 幻读(Phantom Read)](#3. 幻读(Phantom Read))
[1. 查看隔离级别](#1. 查看隔离级别)
[2. 修改隔离级别(两种方式)](#2. 修改隔离级别(两种方式))
[方式二:SET @@语法(更明确)](#方式二:SET @@语法(更明确))
一、事务隔离性的背景:并发 vs 准确,鱼与熊掌如何兼得?
数据库服务器需要并发处理多个客户端的事务(就像"一心两用")。但并发执行很容易"顾此失彼":
-
提高并发性 → 效率高,但数据准确性可能受影响;
-
降低并发性 → 准确性高,但效率变低。
不同场景对"效率"和"准确性"的优先级不同:
-
银行转账:极度关心准确性,效率其次;
-
抖音点赞/评论/转发数:极度关心效率,准确性可妥协;
-
其他场景:两者都兼顾。
二、MySQL的隔离级别:手动设置"隔离强度"
MySQL允许我们手动设置事务的隔离级别,隔离性越强,并发越弱(效率低、准确率高);隔离性越弱,并发越强(效率高、准确率低)。
InnoDB引擎支持四种隔离级别(按隔离性从弱到强):
-
READ UNCOMMITTED(读未提交) -
READ COMMITTED(读已提交) -
REPEATABLE READ(可重复读,MySQL默认) -
SERIALIZABLE(串行化)
三、什么是事务的隔离性?
MySQL服务可被多个客户端同时访问,每个客户端的DML语句以事务 为基本单位。当不同客户端对同一张表的同一条数据修改时,事务之间会相互影响。为保证事务执行时互不影响,这种"互不干扰"的特性就是隔离性。
四、隔离级别的核心:解决"数据不准确"的问题
隔离级别的本质是对事务执行顺序的干预 ,从而解决"数据不准确"的三种典型问题:脏读、不可重复读、幻读。
1. 脏读(Dirty Read)
-
定义:一个事务读取了另一个未提交事务的数据(相当于读了"无效/错误"的数据)。
-
示例(
READ UNCOMMITTED级别): -

-
解决:
READ COMMITTED级别,只允许读取已提交(commit)的数据。
2. 不可重复读(Non-Repeatable Read)
-
定义:同一个事务内,两次读取同一数据,结果不同(因为中间被其他事务修改并提交了)。
-
示例(
READ COMMITTED级别): -

-
解决:
REPEATABLE READ级别,MySQL通过快照机制保证同一事务内多次读取结果一致。
3. 幻读(Phantom Read)
-
定义:同一个事务内 ,两次执行
SELECT,结果集行数不同(因为中间被其他事务插入/删除数据)。是"不可重复读"的扩展(不可重复读是单行数据变,幻读是多行数据变)。 -
示例(
REPEATABLE READ级别,特殊情况): -

-
解决:
SERIALIZABLE级别,事务完全串行执行(一个事务结束,下一个才执行),从根本上杜绝幻读。
五、四个隔离级别的"挡位"与特性(必背!)
把隔离级别类比成"汽车挡位":隔离性越弱(挡位越低),并发越强;隔离性越强(挡位越高),并发越弱。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 并发性能 | 隔离强度(安全性) |
|---|---|---|---|---|---|
READ UNCOMMITTED |
存在 | 存在 | 存在 | 高 | 低 |
READ COMMITTED |
解决 | 存在 | 存在 | 中 | 中 |
REPEATABLE READ |
解决 | 解决 | 存在 | 中低 | 高(MySQL默认) |
SERIALIZABLE |
解决 | 解决 | 解决 | 低 | 最高 |
六、如何查看/修改数据库的隔离级别?
1. 查看隔离级别
-
全局作用域:
SELECT @@GLOBAL.transaction_isolation; -
会话作用域(当前连接):
SELECT @@SESSION.transaction_isolation;
2. 修改隔离级别(两种方式)
方式一:SET语法(临时生效)
-- 全局级别(所有新连接生效,当前连接不生效)
SET GLOBAL transaction_isolation = 'SERIALIZABLE';
-- 注意:空格用'-'代替!
-- 会话级别(当前连接生效,断开后失效)
SET SESSION transaction_isolation = 'REPEATABLE-READ';
方式二:SET @@语法(更明确)
-- 全局级别
SET @@GLOBAL.transaction_isolation = 'SERIALIZABLE';
-- 会话级别
SET @@SESSION.transaction_isolation = 'REPEATABLE-READ';
⚠️ 实际开发建议:修改配置文件,永久生效(需重启MySQL)。
七、不同隔离级别的性能与安全权衡
-
追求安全 :选
SERIALIZABLE(但效率最低); -
平衡安全与效率 :选
REPEATABLE READ(MySQL默认); -
追求效率 :选
READ COMMITTED或READ UNCOMMITTED(但要接受数据不准确风险)。
八、总结(面试话术速记)
事务隔离性是MySQL四大特性(ACID)之一,面试高频考点!记住:
-
隔离级别分4档:
读未提交→读已提交→可重复读→串行化(隔离性递增,并发递减); -
三大问题:脏读(未提交读)、不可重复读(同事务内数据变化)、幻读(同事务内结果集变化);
-
MySQL默认
REPEATABLE READ,通过快照机制解决不可重复读,部分解决幻读; -
可通过
SET GLOBAL/SESSION或配置文件修改隔离级别。
📌 面试技巧:讲清"隔离级别"和"三大问题"的对应关系,结合场景(银行vs抖音)说明取舍,面试官会觉得你不仅背了概念,还理解了本质!
(如果觉得有用,欢迎关注,面试前翻出来过一遍~)