CONTENT
READ-UNCOMMITED(读未提交)
事务A能读到事务B未提交的数据,也就有了脏读,这个事务隔离级别会发生脏读、不可重复读、幻读。
READ-COMMITED(读已提交)
事务只能看到已经提交的数据,事务再提交前的操作对其他事务是不可见的。
这个级别可能会出现不可重复读,事务A先读到了c,但是在事务A提交前,事务B修改了c并且提交了,事务A再读就和原来的不一样了,重复读的结果不一样,还可能出现幻读。
REPEATABLE-READ(可重复读)
同一事务中多次读取同样的记录的结果是一样的,这个MySQL默认的隔离级别。
可能出现幻读,比如事务A读取了某个范围内的记录,事务B再这个范围内插入了新的记录,那么A再次读取的时候就出现了幻行。
在MySQL的InnoDB中快照读通过MVCC解决幻读,当前读通过next-key解决幻读,达到3°。
SERIALIZABEL(可串行化)
强制事务串行执行,避免了前面所有的问题,可能会导致大量超时和锁竞争的问题,用在InnoDB的分布式事务等。
MVCC(多版本并发控制)
InnoDB是通过每行后面保存两个隐藏的列来实现的,分别保存行的创建时间和过期时间,保存时时系统版本号,没开始一个新的事务都会递增这个版本号。
在可重复读下的MVCC:
SELECT:
1)InnoDB只查找早于当前事务版本的数据行,也就是行的系统版本号要小于等于事务的系统版本号,这样可以保证事务读取的行在事务开始前已经存在,要么是事务自己插入或者修改过的。
2)行的删除版本号要么未定义,要么大于事务版本号,确保事务读大的行在事务开始前没有被删除。
INSERT:
1)InnoDB位新插入的行保存当前系统版本号作为行版本号。
DELETE:
1)保存当前版本号作为删除标识
UPDATE:
1)InnoDB为插入一行新的记录,保存当前系统版本号为新行版本号,保存当前版本号为原来行的删除标识。
MVCC只在重复读和读已提交两个隔离级别下工作。
Next-Key Lock
Next-Key Lock是行锁(防止别的事务修改或者删除)与间隙锁(防止其他事务在区间内新增)的组合,这样,当InnoDB扫描索引记录的时候,会首先对选中的索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。如果一个间隙被事务T1加了锁,其它事务是不能在这个间隙插入记录的。
https://www.2cto.com/database/201508/429967.html?faboru=pysuo
快照读和当前读
快照读
简单的select操作
当前读
select ... lock in share mode,对记录加共享锁
select ... for update,排他锁
insert
update
delete