DBMS 中的事务隔离级别

2024 年 8 月 28 日 | 3 分钟阅读

我们知道数据库遵循ACID属性来保持数据库的一致性。数据库有四个属性,我们称这四个属性为ACID属性。ACID属性是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。在这四个属性中,通过隔离性,数据库可以确定事务的完整性如何在系统和用户面前可见。这意味着当只有一个事务正在访问数据库资源时,事务应该在系统中进行。

隔离级别定义了在数据修改期间事务的隔离程度,以及数据库中的其他事务是否会进行这些修改。我们可以通过以下现象来定义事务隔离。

  1. 脏读(Dirty Read):脏读是指一个事务读取了另一个尚未提交的数据。让我们通过一个例子来理解。假设事务1更新了一行,但事务1尚未提交。然后事务2读取了更新后的行。如果事务1回滚更改,那么事务2将读取所有数据,而这些数据将被视为从未存在过。
  2. 不可重复读(Non-Repeatable Read):当一个事务多次读取同一行,并在每次读取时得到不同的值时,就会发生不可重复读。让我们举个例子。假设事务1读取了行数据。但由于并发问题,事务2更新了相同的数据并提交了。现在事务2再次读取同一行,这次得到的值不同了。
  3. 幻读(Phantom Read):当两个查询执行时,它们检索到的行数不同,这时就会发生幻读。让我们举个例子。假设事务1检索了一组满足某些条件的行。现在事务2生成了一些新行,这些新行符合事务1的搜索条件。如果事务1执行读取行的语句,它在不同时间会得到不同的行。

隔离级别

基于以上不同的现象,SQL定义了四种隔离级别。

  1. 读未提交(Read Uncommitted):这是最低的隔离级别。在此级别下,一个事务无法读取其他事务所做的更改,因此它允许脏读。在此级别下,事务之间不隔离。
  2. 读已提交(Read Committed):它保证每个数据在被任何事务读取时都已提交。因此,它不允许脏读。事务会锁定读或写操作,从而防止数据被任何其他事务读取或写入。
  3. 可重复读(Repeatable Read):这是最严格的隔离级别。事务在引用的所有行上持有读锁,并在更新和删除操作引用的行上持有写锁。由于其他事务无法读取、更新或删除这些行,因此可以避免不可重复读。
  4. 串行化(Serializable):这是最高的隔离级别。可以保证串行化执行。串行化执行被定义为一种操作执行方式,其中并发执行的事务看起来像串行执行一样。

下表清楚地描绘了隔离级别、读现象和锁之间的关系

隔离级别脏读不可重复读幻读
读未提交可能发生可能发生可能发生
Read Committed (读已提交)不发生可能发生可能发生
可重复读不发生不发生可能发生
Serializable不发生不发生不发生

示例

举例说明隔离。

事务E的隔离级别是什么?

SET GLOBAL TRANSACTION

ISOLATION LEVEL SERIALIZABLE;

会话结束 会话开始

SET SESSION TRANSACTION

ISOLATION LEVEL REPEATABLE READ;

SET TRANSACTION

ISOLATION LEVEL READ UNCOMMITTED;

SET TRANSACTION

ISOLATION LEVEL READ COMMITTED;

检查哪个选项