这是一个相当基础的问题
SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。
Read Uncommitted(读取未提交内容)
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
Read Committed(读取提交内容)
这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
Repeatable Read(可重读)
这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
Serializable(可串行化)
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
这几行看了不知道多少次了,感觉理解总还是有问题,遂写一下。
理解有障碍的在于Repeatable Read 级别所解决的问题以及幻读的成因。这个级别解决了nonrepatable read的问题。事务A执行期间,事务B的修改操作将不会对A造成影响,因为他会保证在事务中多次读取的同样的记录结果是一致的。
那幻读是什么呢? 幻读是事务A期间,事务B insert了一些记录,事务A在query一个范围内记录的时候恰巧包含了刚插入的记录,导致前后query的结果不一样。
综上,我理解的是可重复读这个级别,其他事务update操作不会对这个事务的query造成影响,但是insert或delete还是会有影响的。
另外,mysql默认的是可重复读的级别,他解决幻读的方式是MVCC。
innoDB的MVCC是通过在每行记录后面保存两个隐藏的列来实现的,这两列,一个保存了行的创建时间,一个保存了过期时间(此处时间不是真的时间,而是版本号)。每个事务,版本号都会递增。下边是可重复读级别下的具体行为
SELECT
Innodb检查每行数据,确保他们符合两个标准:
1、InnoDB只查找版本早于当前事务版本的数据行(也就是数据行的版本必须小于等于事务的版本),这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行
2、行的删除操作的版本一定是未定义的或者大于当前事务的版本号,确定了当前事务开始之前,行没有被删除
符合了以上两点则返回查询结果。
INSERT
InnoDB为每个新增行记录当前系统版本号作为创建ID。
DELETE
InnoDB为每个删除行的记录当前系统版本号作为行的删除ID。
UPDATE
InnoDB复制了一行。这个新行的版本号使用了系统版本号。它也把系统版本号作为了删除行的版本。
网友评论