持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情
概述
前面几篇分别对MySQL的索引和事务都分别做了分析。其中主要包含事物的特性、事务导致的问题、事务通过不同的隔离级别解决事务导致的问题,最后也对事务隔离级别解决事务导致的问题的解决方案做了分析,其中包括使用快照和锁的方案。今天主要是对事务这块的知识做一个简单的小结。
重温InnoDB 隔离级别
第一个隔离级别叫做:Read Uncommitted(未提交读),一个事务可以读取到其他事务未提交的数据,会出现脏读,所以叫做RU,它没有解决任何的问题。
第二个隔离级别叫做:Read Committed(已提交读),也就是一个事务只能读取到其他事务已提交的数据,不能读取到其他事务未提交的数据,它解决了脏读的问题,但是会出现不可重复读的问题。
第三个隔离级别叫做:Repeatable Read (可重复读),它解决了不可重复读的问题,也就是在同一个事务里面多次读取同样的数据结果是一样的,但是在这个级别下,没有定义解决幻读的问题。
最后一个就是:Serializable(串行化),在这个隔离级别里面,所有的事务都是串 行执行的,也就是对数据的操作需要排队,已经不存在事务的并发操作了,所以它解决了所有的问题
MySQL InnoDB 对隔离级别的支持
在MySQL InnoDB里面,不需要使用串行化的隔离级别去解决所有问题。那我们来看一下 MySQL InnoDB里面对数据库事务隔离级别的支持程度是什么样的。
| 事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 未提交读(Read Uncommitted) | 可能 | 可能 | 可能 |
| 已提交读(Read Committed) | 可能 | 可能 | |
| 可重复读(Repeatable Read) | |||
| 串行化(Serializable) |
Read Uncommited
RU 隔离级别:不加锁。
Serializable
Serializable 所有的 select 语句都会被隐式的转化为 select ... in share mode,会和 update、delete 互斥。
这两个很好理解,主要是 RR 和 RC 的区别?
Repeatable Read
RR 隔离级别下,普通的 select 使用快照读(snapshot read),底层使用 MVCC 来实现。
加锁的 select(select ... in share mode / select ... for update)以及更新操作update, delete 等语句使用当,底层使用。
Read Commited
RC 隔离级别下,普通的 select 都是快照读,使用 MVCC 实现。
加锁的 select 都使用记录锁,因为没有 Gap Lock。
除了两种特殊情况——外键约束检查(foreign-key constraint checking)以及重复键检查(duplicate-key checking)时会使用间隙锁封锁区间。
所以 RC 会出现幻读的问题。