数据库复习(事务隔离级别)

在数据库系统中,事务的隔离性(Isolation)是其四大特性(ACID)之一。当多个事务并发执行时,可能会相互干扰,导致数据不一致。为了解决这个问题,SQL标准定义了不同的事务隔离级别,以在数据一致性和系统并发性之间取得平衡。

并发事务带来的问题

在讨论隔离级别之前,我们先了解并发事务可能引发的三种主要问题:

  1. 脏读 (Dirty Read): 一个事务读取到了另一个事务尚未提交的数据。如果后一个事务最终选择回滚,那么第一个事务读取到的就是临时的、无效的“脏”数据。

  2. 不可重复读 (Non-Repeatable Read): 在同一个事务内,两次执行同样的查询返回了不同的结果。这通常是因为在两次查询之间,有另一个事务提交了对这些数据的更新删除操作。重点在于“读”到了数据的变化。

  3. 幻读 (Phantom Read): 在同一个事务内,第二次查询比第一次查询多出了一些“幻影”行。这通常是因为在两次查询之间,有另一个事务提交了插入新行的操作。不可重复读侧重于数据的修改或删除,而幻读侧重于数据的增加。

四种标准隔离级别

SQL 标准定义了四种事务隔离级别,从低到高分别是:

读未提交 (Read Uncommitted)

这是最低的隔离级别。一个事务可以读取到其他事务尚未提交的数据。

  • 存在问题: 脏读、不可重复读、幻读。
  • 优点: 并发能力最强,但数据一致性最差。
  • 应用场景: 几乎没有实际应用场景,因为它连最基本的脏读都无法避免。

读已提交 (Read Committed)

一个事务只能读取到其他事务已经提交的数据。

  • 解决问题: 避免了脏读。
  • 存在问题: 不可重复读、幻读。
  • 特点: 这是大多数主流数据库(如 Oracle, SQL Server, PostgreSQL)的默认隔离级别。

可重复读 (Repeatable Read)

确保在同一个事务中,多次读取同一行数据的结果是一致的。

  • 解决问题: 避免了脏读和不可重复读。
  • 存在问题: 理论上存在幻读。
  • 特点: 这是 MySQL (InnoDB 引擎) 的默认隔离级别。值得注意的是,InnoDB 通过多版本并发控制(MVCC)和 next-key locking 机制,在很大程度上解决了幻读问题,使得在默认配置下,幻读问题很少出现。

串行化 (Serializable)

这是最高的隔离级别。它强制事务串行执行,一个接一个地处理,完全避免了并发问题。

  • 解决问题: 避免了脏读、不可重复读和幻读。
  • 优点: 数据一致性最好。
  • 缺点: 并发性能最差,因为事务需要排队等待,系统吞吐量会显著下降。

总结

下表清晰地展示了各个隔离级别与它们能解决的问题之间的关系:

隔离级别 脏读 (Dirty Read) 不可重复读 (Non-Repeatable Read) 幻读 (Phantom Read)
读未提交 (Read Uncommitted) 允许 允许 允许
读已提交 (Read Committed) 解决 允许 允许
可重复读 (Repeatable Read) 解决 解决 允许
串行化 (Serializable) 解决 解决 解决