面试题:数据库的脏读、不可重复读和幻读分别是什么?

在数据库事务管理中,脏读、不可重复读和幻读是三种常见的并发问题,它们描述了当多个事务同时访问相同的数据时可能出现的问题。以下是这三个概念的详细解释:

1. 脏读(Dirty Read)

定义:脏读指的是一个事务能够读取到另一个事务尚未提交的更改。如果后者回滚了其更改,则前者读取的数据将是无效或“脏”的。

  • 例子:事务 A 修改了一行数据但未提交,此时事务 B 读取了这行被修改的数据。如果之后事务 A 回滚了它的修改,那么事务 B 读取到的就是从未正式存在的数据。
  • 影响:可能导致程序基于错误的数据做出决策。

2. 不可重复读(Non-repeatable Read)

定义:不可重复读是指在一个事务内两次读取同一数据但得到不同的结果。这是因为在这两次读之间,另一个事务修改并提交了这些数据。

  • 例子:事务 A 在时间点 T1 读取某一行数据,在时间点 T2 再次读取同一行数据,但是在这段时间内,事务 B 修改了这一行并已提交。因此,事务 A 在 T1 和 T2 得到的结果不同。
  • 影响:事务无法获取一致性的视图,这对于需要基于先前读取的数据进行比较或者验证的应用来说是个问题。

3. 幻读(Phantom Read)

定义:幻读与不可重复读类似,但它关注的是查询集合的变化而不是单个行的变化。即在一个事务内执行相同的查询可能会返回不同的结果集,因为其他事务插入了新的记录或删除了某些记录。

  • 例子:事务 A 根据某个条件查询一组记录,并在此基础上做一些处理。与此同时,事务 B 插入了一些满足该条件的新记录。当事务 A 再次执行相同的查询时,它会发现额外的记录,就像出现了“幻影”一样。
  • 影响:可能导致事务间的数据不一致性和逻辑错误。

隔离级别

为了应对上述问题,SQL 标准定义了四种事务隔离级别,每个级别提供了不同程度的保护来防止这些问题的发生:

  • 读未提交(Read Uncommitted):最低级别的隔离,允许所有形式的并发问题发生。
  • 读已提交(Read Committed):解决了脏读问题,但可能仍会出现不可重复读和幻读。
  • 可重复读(Repeatable Read):默认级别之一,解决了脏读和不可重复读,但在某些情况下仍可能出现幻读。
  • 串行化(Serializable):最高级别的隔离,完全避免了脏读、不可重复读以及幻读,但代价是性能下降,因为它限制了事务的并发程度。

选择合适的隔离级别取决于应用的具体需求以及对一致性、并发性和性能之间的权衡。

THE END
喜欢就支持一下吧
点赞7 分享