一、数据库读现象
读现象在本质上来说,是数据库在高并发场景下,多个同时执行的事务带来的影响。
数据库主要有三大常见的读现象:
脏读:事务1和事务2并发执行,事务1改了数据,事务2读取了以后,但事务1进行了回滚,导致事务2读取的数据有误。
不可重复读:事务1读取了数据,事务2修改了数据并且提交了,接着事务1再次读取,发现两次的数据不相同
幻读:本质上说是不可重复读的一种现象,事务1更改或查询了数据,在极短时间内,事务2又插入了一条新的数据,导致事务1在接下来的查询中,就会发现有⼏列数据是它先前所没有的。
解决办法:要解决脏读,不可重复读和幻读的问题,我们就要引入几个概念:MVCC机制,事务隔离机制和数据库锁机制。
二、数据库事务隔离机制
事务具有原子性、一致性、隔离性、持久性四大特性,而隔离性顾名思义指的就是事务彼此之间隔离开,多个事务在同时处理一个数据时彼此之间互相不影响,如如果隔离的不够好就有可能会产生脏读、不可重复度、幻读等读现象,为此,隔离性总共分为四种级别
由低到高依次为Read uncommitted(未提交读) 、Read committed (提交读)、Repeatable read(可重复读) 、Serializable(串行化),这些级别分别依次解决了脏读,不可重复读和幻读的问题
而MySQL的存储引擎默认的隔离级别为Repratable read (可重复读),于是解决了脏读和不可重复读的问题,至于幻读问题,MySQL引入了Next-key lock的行级锁来解决,我们将会在下一节里详细叙述
三、MVCC机制
MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC (Multi-Version Concurrency Control) 。MVCC最大的好处是:读不加锁,读写不冲突。这个机制解决了数据的脏读问题。
MVCC的并发控制的系统中,读操作可分为两类:当前读和快照读。
快照读:简单的select操作,属于快照读,不加锁。
当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。