MySQL 事务实战指南
1. MySQL 事务隔离级别
MySQL 事务隔离级别主要分为以下四种:
- 读未提交(Read Uncommitted):允许读取尚未提交的数据变更,可能会导致脏读。
- 读已提交(Read Committed):允许读取并发事务已经提交的数据,可以防止脏读,但无法避免不可重复读和幻读。
- 可重复读(Repeatable Read):在一个事务内多次读取相同记录的结果是一致的,可以防止脏读和不可重复读,但无法避免幻读。
- 串行化(Serializable):完全串行化执行所有事务,确保事务之间不会相互影响,可以防止脏读、不可重复读和幻读,但性能较差。
2. 设置隔离级别与查看配置
通过以下命令设置隔离级别:
SET TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE];
查看当前隔离级别配置:
SHOW VARIABLES LIKE 'transaction_isolation';
3. InnoDB 的 MVCC 实现机制
InnoDB 使用 MVCC(多版本并发控制)实现非阻塞的读写操作。其核心机制包括:
- 数据版本号:每行数据都有一个版本号,用于区分不同版本的数据。
- undo 日志:记录对数据的修改操作,用于回滚和恢复数据。
- Read View:在读取数据时生成的一个快照,用于确定可见的数据版本。
4. MVCC 与锁的性能差异
MVCC 通过非阻塞的方式实现读写操作,而悲观锁会锁定整个资源或范围。因此,MVCC 在高并发场景下具有更好的性能。
5. 可重复读级别下 MVCC 工作流程与幻读避免
在可重复读级别下,一个事务在整个生命周期内使用相同的 Read View。这样,即使其他事务修改了数据,当前事务也能看到一致的结果。RR 避免了幻读的发生。
6. 读已提交级别中 Read View 的生成时机与锁竞争降低
在 RC 级别下,每次读取数据时都会生成一个新的 Read View。这导致锁竞争降低,因为不需要锁定整个资源或范围。
7. 不同隔离级别下的锁行为对比
隔离级别 | 锁行为 |
---|---|
RC | 快照读无锁 |
RR | 间隙锁防止幻读 |
8. 脏读、不可重复读、幻读的复现与解决方案
脏读
-- 开启一个新的事务
START TRANSACTION;
-- 插入一条新记录
INSERT INTO test (id, name) VALUES (1, 'test');
-- 查询该记录
SELECT * FROM test WHERE id = 1;
-- 回滚事务
ROLLBACK;
-- 再次查询该记录
SELECT * FROM test WHERE id = 1;
解决方法:将隔离级别设置为 RR 或 SERIALIZABLE。
不可重复读
-- 开启两个新的事务
START TRANSACTION;
-- 查询一条记录
SELECT * FROM test WHERE id = 1;
-- 在另一个事务中修改该记录
UPDATE test SET name = 'update' WHERE id = 1;
-- 在第一个事务中再次查询该记录
SELECT * FROM test WHERE id = 1;
-- 回滚第二个事务
ROLLBACK;
解决方法:将隔离级别设置为 RR 或 SERIALIZABLE。
幻读
-- 开启两个新的事务
START TRANSACTION;
-- 查询某条记录的范围内的所有记录数量
SELECT COUNT(*) FROM test WHERE id > 0 AND id < 10;
-- 在另一个事务中插入一条新记录到该范围内
INSERT INTO test (id, name) VALUES (5, 'insert');
-- 在第一个事务中再次查询该范围内的所有记录数量
SELECT COUNT(*) FROM test WHERE id > 0 AND id < 10;
解决方法:将隔离级别设置为 RR 或 SERIALIZABLE。
9. Undo 日志管理优化
调整 innodb_undo_retention
参数可以优化 undo 日志管理:
SET GLOBAL innodb_undo_retention = [秒];
这可以避免长事务导致的回滚段膨胀。
10. SHOW ENGINE INNODB STATUS 输出分析
分析 SHOW ENGINE INNODB STATUS
输出中的 MVCC 相关信息可以帮助定位事务版本冲突问题。
11. 金融场景与高并发场景的隔离级别选择策略
金融场景(需强一致性)推荐使用 SERIALIZABLE 隔离级别;高并发场景(需性能优先)推荐使用 REPEATABLE READ 或 READ COMMITTED 隔离级别。
12. 串行化隔离级别的适用场景及性能影响
串行化隔离级别适用于对一致性要求极高的场景。但其性能较差,因为会阻塞其他并发操作。
13. MVCC 与行锁、表锁的协同机制及快照读与当前读的区别
MVCC 与行锁、表锁协同工作以实现非阻塞读写操作。快照读只读取数据的旧版本而不加锁;当前读取的是最新版本并加锁。