MySQL 事务隔离级别与MVCC

一、隔离级别

参考了维基百科:事務隔離

隔离级别规定了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的。

下面对隔离级别的说明都是基于锁机制并发控制的数据库管理系统而言。

1. 可序列化(Serializable)

实现可序列化要求在选定对象上的读锁和写锁保持直到事务结束后才能释放。在 SELECT 的查询中使用一个 WHERE 子句来描述一个范围时应该获得一个“范围锁(range-locks)”。这种机制可以避免“幻影读(phantom reads)”现象。

可序列化是最高级别的隔离。

2. 可重复读(Repeatable read)

该级别保证了同一个事务中多次读取同样的记录的结果是一致的。

对选定对象的读锁(read locks)和写锁(write locks)一直保持到事务结束,但不要求“范围锁(range-locks)”,因此可能会发生“幻影读(phantom reads)”。

幻影读:是因为没有保持范围锁,该事务执行了一个 where 子句的范围查询后,其他事务可能新增了一条处于该事务 where 查询范围内的记录,那么该事务再次执行范围查询时就会看到这些新增的记录行(幻行,Phantom row)。

可重复读是 MySQL 的默认事务隔离级别。

3.提交读(Read committed)

该级别也叫不可重复读(nonrepeatable read)。

DBMS需要对选定对象的写锁(write locks)一直保持到事务结束,但是读锁(read locks)在SELECT操作完成后马上释放(因此“不可重复读”现象可能会发生,见下面描述)。和前一种隔离级别一样,也不要求“范围锁(range-locks)”。

不可重复读是因为,事务只维持了选定对象的写锁,如果一些选定对象只涉及读锁,那么在读锁释放之后,其它事务可以对这些对象进行修改,该事务再次读取时就不一致了。

大多数数据库的默认事务隔离级别都是这个。

4. 未提交读(Read uncommitted)

也称为脏读(dirty read)。

一个事务可以读取到其它事务未提交的更改。

不可重复读的重点是修改:同样的条件,读取过的数据,再次读取出来发现值不一样了。

幻读的重点在于新增或者删除:同样的条件,第 1 次和第 2 次读出来的记录数不一样。

继续阅读