隔离级别

41次阅读
没有评论

数据库的隔离级别(Isolation Levels)是用来解决多个事务并发执行时,可能出现的互相干扰问题的。

为了权衡数据一致性系统并发性能,SQL 标准定义了四个隔离级别。级别越高,数据越安全,但并发性能越差。


1. 并发事务会引发的三个“怪现象”

在了解隔离级别前,必须先知道它们要解决的“三大问题”:

  1. 脏读 (Dirty Read):事务 A 读取了事务 B 还没提交的数据。如果事务 B 随后回滚,事务 A 读到的就是过期且不存在的假数据。

  2. 不可重复读 (Non-repeatable Read):事务 A 多次读取同一条记录。在两次读取之间,事务 B 修改并提交了数据。导致事务 A 两次读到的内容不一样。

  3. 幻读 (Phantom Read):事务 A 按某个条件查询一批记录。在两次查询之间,事务 B 插入或删除了数据。导致事务 A 发现记录变多或变少了。


2. 四种隔离级别对比

隔离级别 脏读 不可重复读 幻读 性能 备注
读未提交 (Read Uncommitted) ❌ 有 ❌ 有 ❌ 有 🚀 极高 基本不用,非常危险。
读已提交 (Read Committed) ✅ 无 ❌ 有 ❌ 有 📈 高 Oracle/PostgreSQL 的默认级别。
可重复读 (Repeatable Read) ✅ 无 ✅ 无 ❌ 有* 📊 中 MySQL (InnoDB) 的默认级别。
串行化 (Serializable) ✅ 无 ✅ 无 ✅ 无 🐢 极低 强制事务排队执行,完全没有并发。

*注:MySQL 的 InnoDB 引擎通过 Next-Key Lock 机制,在“可重复读”级别下其实已经很大程度上解决了幻读问题。


3. 深度解析:不同级别的实现原理

① 读已提交 (RC):每次都看最新的

每次执行 SELECT 语句时,数据库都会重新生成一个快照(Read View)。所以如果你在同一个事务里查两次,而中间有人改了数据,你两次看到的快照是不一样的。

② 可重复读 (RR):只看一眼,记一辈子

只有在事务开始后的第一次 SELECT 时生成快照。后续所有的查询都复用这同一个快照。这就是为什么别人怎么改,你查出来的结果都一样。

③ 串行化 (Serializable):排队走

它不再使用快照,而是给读到的每一行数据都加共享锁(S Lock)。如果有人想改数据,必须等你的事务结束。这就像大家排成一队过独木桥,效率非常低,但绝对安全。


4. 生产环境如何选择?

  • 大多数互联网公司:选择 读已提交 (RC)

    • 原因:RC 配合乐观锁能应对绝大多数高并发场景,且不会像 RR 那样因为锁太多(间隙锁)导致死锁风险。

  • 金融/计费系统:通常维持 可重复读 (RR) 或更高。

    • 原因:对账务的一致性要求极高,不能容忍任何数据飘移。


5. 总结

隔离级别本质上是 “锁”“版本快照” 的博弈:

  • :保证安全,但会互相等待。

  • 快照 (MVCC):保证并发,各看各的,互不干扰。

既然聊到了隔离级别,你想了解一下在你的 Java 应用中,如何通过 Spring 的 @Transactional(isolation = Isolation.REPEATABLE_READ) 来灵活控制代码块的隔离级别吗?

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-03-23发表,共计1208字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)