InnoDB的四种事务隔离级别是如何实现的?

版权声明:转载请注明出处! https://blog.csdn.net/litianxiang_kaola/article/details/83061230

事务的介绍看这篇博客: MySQL架构基础

并发控制的介绍看这篇博客: InnoDB并发控制

本篇博客介绍InnoDB的四种事务隔离级别是如何实现的, 需要事先阅读上面的两篇博客.

REPEATABLE READ

InnoDB并发控制 这篇博客最后一部分对REPEATABLE READ隔离级别是如何实现做了详细介绍, 这里做个简单的归纳.

普通的SELECT

快照读, 即不加锁的一致性读. 在同一个事务中, 所有的select操作都是读取的第一次select所建立的快照, 这就解决了不可重复读的问题.

加锁SELECT/UPDATE/DELETE

(1)在唯一索引(PRIMARY KEY和UNIQUE KEY) 上使用唯一的查询条件时, 加记录锁.

(2)其他情况使用间隙锁或者临键锁(InnoDB使用的是临键锁, 因为间隙锁可以被显示禁用). 间隙锁和临键锁解决了幻读的问题.

INSERT

在插入索引间隔内加插入意向锁, 对具体的插入行加记录锁.

READ COMMITTED

普通的SELECT

快照读, 即不加锁的一致性读. 与REPEATABLE READ隔离级别不同的是, 每一次一致性读取, 即使在同一事务中, 也会设置和读取它自己的新快照, 这就会导致不可重复读的问题.

快照读解决了脏读的问题.

加锁SELECT/UPDATE/DELETE

除了在外键约束检查(foreign-key constraint checking)以及重复键检查(duplicate-key checking)时会封锁区间, 其他时刻都只使用记录锁, 这就会导致幻读的问题.

INSERT

在插入索引间隔内加插入意向锁, 对具体的插入行加记录锁.

READ UNCOMMITTED

与READ COMMITTED的差别在于, 该隔离级别下没有使用快照读, 而是以不加锁的方式执行SELECT语句, 这就会导致脏读问题.

SERIALIZABLE

该隔离级别与REPEATABLE READ类似, 只有一点区别: 当禁用 autocommit 时, InnoDB会把普通的SELECT隐式地转换成SELECT … LOCK IN SHARE MODE. 这就会导致一个问题, 当有未提交的事务正在修改某些行,所有读取这些行的select都会被阻塞住(读写不能并发进行).

展开阅读全文

没有更多推荐了,返回首页