MySQL 事务隔离级别和幻读问题
Spring 事务用起来简单,但失效场景非常多。很多人遇到过 @Transactional 不生效的情况,却不知道原因。本文把日常开发中常见的坑和对应的排查思路整理出来,帮你避免踩坑。
准备一张示例表
以订单表为例:
CREATE TABLE orders ( |
查询订单列表时,很多人会直接写:
SELECT * FROM orders |
这时可以考虑组合索引:
CREATE INDEX idx_user_status_time |
必须用 EXPLAIN 验证
优化 SQL 不要凭感觉,先看执行计划:
EXPLAIN SELECT * FROM orders |
重点看 key 是否命中索引,rows 是否明显下降。如果只是建了索引但执行计划没变化,那说明索引设计可能不贴合查询条件。
常见坑
- 在索引列上使用函数,可能导致索引失效。
- 字段类型不一致,例如字符串和数字混用,会影响优化器选择。
- 大 offset 分页会越来越慢,可以改成基于 id 的游标分页。
核心要点
事务失效的常见原因:非 public 方法、自调用、异常被吞掉、错误的传播级别
事务传播级别决定了方法之间的事务关系,REQUIRED 是默认值
使用 @Transactional(rollbackFor = Exception.class) 确保异常回滚
编程式事务在某些场景下比声明式事务更灵活
总结
事务管理是保证数据一致性的关键。理解事务的工作机制和常见陷阱,能帮你写出更健壮的代码。在实际项目中,合理配置事务边界非常重要。