innodb事务隔离级别

一、定义#

未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
提交读(Read Committed):只能读取到已经提交的数据. 可以阻止脏读,但是可能发生幻读或不可重复读
可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的. 可以阻止脏读和不可重复读,幻读通过mvcc解决了快照读,next-key锁解决了当前读. mysql默认隔离级别.
串行读(Serializable):读加共享锁,写加排他锁,读写互斥.

可重复读指的是同一行在同一个事务下无论怎么读取都是同一个结果(除非自己把它改了).

幻读指的是在同一事务下,连续执行两次同样的SQL语句第二次的SQL语句可能返回之前不存在的行;

二、什么是快照读,什么是当前读#

快照读:就是select

1
select * from table ….;

当前读:特殊的读操作,插入/更新/删除操作,属于当前读,处理的都是当前的数据,需要加锁。

1
2
3
4
5
select * from table where ? lock in share mode;
select * from table where ? for update;
insert;
update ;
delete;

事务的隔离级别实际上都是定义了当前读的级别,MySQL为了减少锁处理(包括等待其它锁)的时间,提升并发能力,引入了快照读的概念,使得select不用加锁。而update、insert这些“当前读”,就需要另外的模块来解决了

三、rr级别下mvcc解决不可重复读和快照读之间的幻读#

一致非锁定读,也可以称为快照读,即普通SELECT语句,既然是快照读,故 SELECT 的时候,会生成一个快照。

生成快照的时机:事务中第一次调用SELECT语句的时候才会生成快照,在此之前事务中执行的update、insert、delete操作都不会生成快照

REPEATED READ 隔离级别下,快照会在事务中第一次SELECT语句执行时生成,只有在本事务中对数据进行更改才会更新快照,因此,只有第一次SELECT之前其它已提交事务所作的更改你可以看到,但是如果已执行了SELECT,那么其它事务commit数据,你SELECT是看不到的。

四、rr级别下next-key锁解决当前读之间的幻读#

在当前读下rr级别使用了next-key锁(临键锁),临键锁包括行锁+间隙锁, 来避免两个当前读时有其它事务插入数据,所以当前读使用next-key锁解决的幻读。

最后备注下:如果是先快照读再当前读,影响行数不一致是否属于幻读,是有争议的但大多认为并不是幻读。

五、rr和rc区别#

rc级别下的mvcc总是读取数据行的最新快照,而rr级别下的mvcc,会在事务第一次select的时候,为数据行生成一个快照,后面每次都读这个快照,除非自己更新

如果问,rr为什么是默认的隔离级别,就说rr相比rc来说没有不可重复读和幻读问题. 后面再深入研究

六、todo学习#

  1. rr为什么是默认的隔离级别
  2. mvcc在rc隔离级别下,读最新的快照,为什么不直接读行记录呢,rc级别是怎么解决脏读的

参考文章#

https://tech.meituan.com/2014/08/20/innodb-lock.html

# mysql
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×