MySQL 的事务隔离级别是数据库管理系统中非常重要的概念,它决定了事务之间的隔离程度,直接影响数据一致性和并发性能。MySQL 支持四种标准隔离级别(基于 SQL:92 标准):
- READ UNCOMMITTED(读未提交) :可能出现脏读。 2. READ COMMITTED(读已提交) :避免脏读,但可能出现不可重复读。 3. REPEATABLE READ(可重复读) :MySQL 的默认隔离级别,避免脏读和不可重复读,但可能出现幻读(InnoDB 通过 MVCC 和间隙锁部分解决)。 4. SERIALIZABLE(串行化):最高隔离级别,完全避免并发问题,但性能较低。
在 MySQL 中,可以通过配置或命令动态修改隔离级别,具体方法如下:
1. 查看当前隔离级别
在修改之前,先确认当前的隔离级别。可以通过以下 SQL 语句查看:
sql
SELECT @@transaction_isolation; -- MySQL 8.0 之前
SELECT @@tx_isolation; -- MySQL 5.7 及更早版本
输出可能是 REPEATABLE-READ
(默认值)等。
2. 修改隔离级别
MySQL 支持在全局级别和会话级别修改隔离级别。
(1) 修改会话级别的隔离级别
如果你只想在当前会话中更改隔离级别,可以使用以下命令:
sql
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
SESSION
表示只对当前会话有效。 - 可替换的选项包括:READ UNCOMMITTED
、READ COMMITTED
、REPEATABLE READ
、SERIALIZABLE
。
修改后,可以再次运行 SELECT @@transaction_isolation;
验证是否生效。
(2) 修改全局级别的隔离级别
如果需要更改整个数据库的默认隔离级别,可以使用:
sql
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
GLOBAL
表示对所有新连接生效,但已存在的连接不会受影响。 - 同样支持上述四种隔离级别。
(3) 通过配置文件修改(持久化)
为了让隔离级别在 MySQL 重启后仍然有效,可以修改配置文件(通常是 my.cnf
或 mysqld.cnf
)。在 [mysqld]
部分添加:
ini
[mysqld]
transaction-isolation = READ-COMMITTED
保存后重启 MySQL 服务:
bash
sudo systemctl restart mysql
注意:配置文件中的值需要使用连字符(-
),而不是下划线(_
)。
3. 验证修改效果
修改完成后,可以通过以下方式验证: - 开启两个会话窗口,分别执行事务,观察并发行为是否符合预期隔离级别。 - 比如在 READ UNCOMMITTED
下,一个事务的未提交更改在另一个事务中可见(脏读)。
4. 注意事项
- 权限 :修改全局隔离级别需要
SUPER
权限。 - 存储引擎 :隔离级别主要适用于 InnoDB(MySQL 默认引擎),MyISAM 不支持事务和隔离级别。 - 性能与一致性权衡 :降低隔离级别(如READ UNCOMMITTED
)可能提升并发性能,但会牺牲数据一致性;提高隔离级别(如SERIALIZABLE
)则相反。
5. 面试加分点
如果这是面试复盘,可以补充一些扩展内容: - 为什么用 REPEATABLE READ 作为默认? InnoDB 通过多版本并发控制(MVCC)和间隙锁优化了幻读问题,兼顾性能和一致性。 - 实际场景举例:电商库存扣减可能需要更高的隔离级别(避免超卖),而日志查询可以用较低的隔离级别。