MySQL-事务隔离级别

CONTENT

READ-UNCOMMITED

READ-COMMITED

REPEATABLE-READ

SERIALIZABEL

MVCC

Next-Key Lock

快照读和当前读

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

posted @ 2019-08-10 11:41  KuroNJQ  阅读(127)  评论(0编辑  收藏  举报