- 脏读:从另一个事务中读取 UNCOMMITED 数据
- 不可重复读取
UPDATE
:从另一个事务的查询中读取 COMMITTED 数据
- 幻读
INSERT
:从另一个事务中读取或DELETE
查询中的 COMMITTED 数据
注意:来自另一个事务的 DELETE 语句在某些情况下也极有可能导致不可重复读取。不幸的是,当 DELETE 语句删除了您当前事务正在查询的同一行时,就会发生这种情况。但这是一种罕见的情况,并且不太可能发生在每个表中有数百万行的数据库中。在任何生产环境中,包含事务数据的表通常具有很高的数据量。
此外,我们可能会观察到,在大多数用例中,UPDATES 可能是比实际 INSERT 或 DELETES 更频繁的工作(在这种情况下,仅存在不可重复读取的危险-在这些情况下不可能进行幻读)。这就是为什么 UPDATES 的处理方式与 INSERT-DELETE 不同,由此产生的异常也有不同的命名方式。
还有与处理 INSERT-DELETE 相关的额外处理成本,而不仅仅是处理 UPDATES。
- READ_UNCOMMITTED 不会阻止任何事情。这是零隔离级别
- READ_COMMITTED 只防止一个,即脏读
- REPEATABLE_READ 防止两个异常:脏读和不可重复读
- SERIALIZABLE 可防止所有三种异常情况:脏读、不可重复读和幻读
那么为什么不一直设置事务 SERIALIZABLE 呢?好吧,上述问题的答案是:SERIALIZABLE 设置使交易变得非常缓慢,这也是我们不想要的。
事实上,交易时间消耗是在以下比率:
SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED > READ_UNCOMMITTED
所以 READ_UNCOMMITTED 设置是最快的。
概括
实际上,我们需要分析用例并确定隔离级别,以便我们优化事务时间并防止大多数异常。
请注意,默认情况下数据库可能具有 REPEATABLE_READ 设置。管理员和架构师可能倾向于选择此设置作为默认设置,以展示更好的平台性能。