类比:多人同时编辑同一份文档(如在线表格)。如果没有规则,你会看到别人未保存的草稿(脏数据),或者自己的操作被覆盖。隔离级别的作用:定义不同用户操作数据的“可见范围”,平衡安全性与性能。
隔离级别 | 脏读 | 不可重复读 | 幻读 | 性能对比 | 典型问题场景 |
---|---|---|---|---|---|
读未提交 | 可能 | 可能 | 可能 | ⚡️ 最高 | 用户A看到用户B未提交的订单取消,但B最终回滚 |
读已提交 | 避免 | 可能 | 可能 | 高 | 用户A两次查询账户余额结果不同(在事务中B提交了更新) |
可重复读 | 避免 | 避免 | 可能* | ⏱️ 中等(MySQL默认) | 用户A统计订单数时,用户B新增订单导致两次统计结果不一致 |
串行化 | 避免 | 避免 | 避免 | ⏳ 最低 | 完全避免并发问题,但事务需排队执行 |
⚠️ *注:MySQL的“可重复读”通过间隙锁(Gap Lock)解决了大部分幻读问题
--查看全局隔离级别
select @@global.transaction_isolation;
--查看当前回话隔离级别
select @@session.transaction_isolation;
2. 设置全局隔离级别(需管理员权限)
set global transaction isolation level read committed;
- 持久化到配置文件(my.cnf或my.ini)
[mysqld]
transaction-isolation = READ-COMMITTED
-- 设置为可重复读
set session transaction isolation level read committed;
-- 下一个事务将使用指定级别;
set transaction isolation level serializable
BEGIN; -- 事务开始
语法规则:
-
或 _
连接(如 READ-COMMITTED
或 READ_COMMITTED
)。问题验证:
步骤1:用户A开启事务并修改数据(不提交)。
START TRANSACTION;
UPDATE account SET balance = 500 WHERE id = 1;
步骤2:用户B设置为读未提交,并查询:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT balance FROM account WHERE id = 1; -- 显示500(脏读)
问题验证:
-- 用户A事务:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
SELECT balance FROM account WHERE id = 1; -- 返回1000
-- 用户B提交更新:
UPDATE account SET balance = 800 WHERE id = 1;
COMMIT;
-- 用户A再次查询:
SELECT balance FROM account WHERE id = 1; -- 返回800(不可重复读)
应用场景:多数 OLTP 系统(如电商订单处理),需实时准确的数据。
问题验证:
-- 用户A:
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
SELECT COUNT(*) FROM account WHERE balance > 1000; -- 返回3
-- 用户B:
INSERT INTO account (balance) VALUES (1500);
COMMIT;
-- 用户A再次查询:
SELECT COUNT(*) FROM account WHERE balance > 1000; -- 仍返回3(无幻读,因快照)
-- 但若用户A执行更新操作:
UPDATE account SET balance = balance - 100 WHERE balance > 1000; -- 更新包含新插入行
解决方案:MySQL的 MVCC 机制通过创建数据快照避免大部分幻读。
验证流程:
-- 用户A:
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;
SELECT * FROM account WHERE id = 1 FOR UPDATE; -- 加锁
-- 用户B尝试修改:
BEGIN;
UPDATE account SET balance = 200 WHERE id = 1; -- 阻塞,直到用户A提交
应用场景:金融核心系统(如资金清算),严格要求数据一致性。
业务需求 | 推荐隔离级别 | 理由 |
---|---|---|
高并发读取,容忍误差 | 读已提交 | 平衡性能与数据可见性 |
数据强一致,避免幻读 | 可重复读 | 默认级别,通过快照和间隙锁控制 |
严格事务序列化 | 串行化 | 牺牲性能,完全避免并发问题 |
SHOW ENGINE INNODB STATUS
分析死锁日志。