全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-15 7 分钟 ✍️ juanwangdev

MySQL 事务隔离级别

事务隔离级别决定了并发事务之间的可见性,是平衡性能与数据一致性的关键。

四种隔离级别

级别脏读不可重复读幻读性能
READ UNCOMMITTED可能可能可能最高
READ COMMITTED不可能可能可能较高
REPEATABLE READ不可能不可能可能较低
SERIALIZABLE不可能不可能不可能最低

并发问题说明

SQL
-- 脏读:读到其他事务未提交的数据
-- 事务A                               事务B
UPDATE users SET age=20 WHERE id=1;
                                       SELECT age FROM users WHERE id=1;  -- 读到20
ROLLBACK;
                                       -- 事务B读到的数据无效

-- 不可重复读:同一事务两次读取结果不同
-- 事务A                               事务B
SELECT age FROM users WHERE id=1;  -- 18
                                       UPDATE users SET age=20 WHERE id=1;
                                       COMMIT;
SELECT age FROM users WHERE id=1;  -- 20,两次结果不同

-- 幻读:同一事务两次查询记录数不同
-- 事务A                               事务B
SELECT * FROM users WHERE age>18;  -- 3条
                                       INSERT INTO users VALUES(5,'新用户',25);
                                       COMMIT;
SELECT * FROM users WHERE age>18;  -- 4条,多了一条"幻影"

设置隔离级别

SQL
-- 全局设置
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 会话设置
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 下一个事务设置
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 查看隔离级别
SELECT @@transaction_isolation;
SELECT @@global.transaction_isolation;

READ UNCOMMITTED 读未提交

SQL
-- 可能读到脏数据,实际很少使用
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION;
SELECT * FROM accounts WHERE id = 1;  -- 可能读到其他事务未提交的修改
COMMIT;

READ COMMITTED 读已提交

SQL
-- Oracle、SQL Server 默认级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT balance FROM accounts WHERE id = 1;  -- 只能看到已提交的数据
-- 其他事务提交后再次查询可能结果不同(不可重复读)
SELECT balance FROM accounts WHERE id = 1;
COMMIT;

REPEATABLE READ 可重复读

SQL
-- MySQL 默认级别,通过 MVCC 实现
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT balance FROM accounts WHERE id = 1;  -- 第一次读取
-- 其他事务提交修改后
SELECT balance FROM accounts WHERE id = 1;  -- 结果相同
COMMIT;  -- 提交后才能看到新数据

MySQL 通过 MVCC 在 REPEATABLE READ 级别也基本解决了幻读问题。

SERIALIZABLE 序列化

SQL
-- 最高隔离级别,所有事务串行执行
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
SELECT * FROM accounts;  -- 会锁定整表,其他事务等待
COMMIT;

实际开发中常用 READ COMMITTED 或 REPEATABLE READ。

要点总结

  • MySQL 默认隔离级别是 REPEATABLE READ
  • READ COMMITTED 解决脏读,Oracle 默认
  • REPEATABLE READ 解决脏读和不可重复读
  • SERIALIZABLE 解决所有问题,但性能最低
  • MySQL 通过 MVCC 在 RR 级别基本解决幻读

📝 发现内容有误?点击此处直接编辑

← 上一篇 MySQL 事务ACID特性
下一篇 → MySQL 死锁与优化
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库