MySQL程序员面试笔试宝典
上QQ阅读APP看书,第一时间看更新

4.5 事务的4种隔离级别(Isolation Level)分别是什么?

当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,所以,对于不同的事务,采用不同的隔离级别会有不同的结果。如果不考虑事务的隔离性,那么会发生下表所示的3种问题:

脏读和不可重复读的区别为:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是在同一个事务范围内多次查询同一条数据却返回了不同的数据值,这是由于在查询间隔期间,该条数据被另一个事务修改并提交了。

幻读和不可重复读的区别为:幻读和不可重复读都是读取了另一个事务中已经提交的数据,不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一个数据整体(例如数据的条数)。

在SQL标准中定义了4种隔离级别,每一种级别都规定了一个事务中所做的修改,哪些是在事务内和事务间可见的,哪些是不可见的。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。SQL标准定义的四个隔离级别为:Read Uncommitted(未提交读)、Read Committed(提交读)、Repeatable Read(可重复读)、Serializable(可串行化),下面分别介绍。

(1)Read Uncommitted(未提交读,读取未提交内容)

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果,即在未提交读级别,事务中的修改,即使没有提交,对其他事务也都是可见的,该隔离级别很少用于实际应用。读取未提交的数据,也被称之为脏读(Dirty Read)。该隔离级别最低,并发性能最高。

(2)Read Committed(提交读,读取提交内容)

这是大多数数据库系统的默认隔离级别。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。

(3)Repeatable Read(可重复读)

可重复读可以确保同一个事务,在多次读取同样数据的时候,得到同样的结果。可重复读解决了脏读的问题,不过理论上,这会导致另一个棘手的问题:幻读(Phantom Read)。MySQL数据库中的InnoDB和Falcon存储引擎通过MVCC(Multi-Version Concurrent Control,多版本并发控制)机制解决了该问题。需要注意的是,多版本只是解决不可重复读问题,而加上间隙锁(也就是它这里所谓的并发控制)才解决了幻读问题。

(4)Serializable(可串行化、序列化)

这是最高的隔离级别,它通过强制事务排序,强制事务串行执行,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能出现大量的超时现象和锁竞争。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑用该级别。这是花费代价最高但是最可靠的事务隔离级别。

不同的隔离级别有不同的现象,并有不同的锁和并发机制,隔离级别越高,数据库的并发性能就越差,4种事隔离级别与并发性能的关系如下: