mysql事务隔离级别

2019-10-14  本文已影响0人  Easy的幸福
msyql的事务隔离级别如下:

事务中的修改,即使没有提交,对其它事务也是可见的. 脏读(Dirty Read).

一个事务开始时,只能"看见"已经提交的事务所做的修改. 这个级别有时候也叫\color{red}{不可重复读}

强制事务串行执行,避免了上面说到的 脏读,不可重复读,幻读 三个的问题.

mysql默认的隔离级别其实是没有解决可重复读和幻读的问题,但是它还是给解决了。
mvcc多版本并发控制(Multi-Version Concurrency Control)

InnoDB的MVCC是通过在每行记录后面保存2个隐藏的列来实现的,一列保存了行的创建时间,一列保存了行的过期时间(或删除时间),但它们实际都存储的是系统版本号。

\color{red}{MVCC最大的作用是: 实现了非阻塞的读操作,写操作也只锁定了必要的行.}
mysql的mvcc只在 Read Committed和 Repeatable read两个隔离级别下工作。

在MVCC机制下,mysql\color{red}{默认隔离界}别下的增删改查变成如下模式。

读模式:

写模式:

一致性非锁定读,是InnoDB存储引擎下的读取数据的方式( read committed 和 repeatable read).

一致性非锁定读,我的理解是它的读取方式是把: 事务隔离级别,MVCC,InnoDB锁结合起来运用到实现 Mysql读的一种方式.

一致性非锁定读总是读取被锁定行的最新一份(最新的一行)快照数据. 产生了不可重复读的问题.

一致性非锁定读总是读取事务开始时(第一行)的行数据版本. 解决不可重复读的问题

一致性锁定读
InnoDB 锁的算法

间隙锁,它会锁住两个索引之间的区域。比如select * from user where id>1 and id<10 for update,就会在id为(1,10)的索引区间上加Gap Lock。

也叫间隙锁,它是Record Lock + Gap Lock形成的一个闭区间锁。比如select * from user where id>=1 and id<=10 for update,就会在id为[1,10]的索引闭区间上加Next-Key Lock

\color{red}{innoDB在不同隔离级别下产生"不可重复读" 和 "幻读" 和解决它 的根本原因}

Next-key lock的具体实现:

默认存储引擎下, 比如表A 上的id字段有索引, 并且id有 3,8,12,20这几个值,那么该索引可能被Next-key locking区间为:

负无穷,3)[3,8)[8,12),[12,20),[20,正无穷),当事务T1锁定了 [8,12),[12,20)这2个区间时,当插入15时,上面的区间变成:[8,12),[12,15),[15,20)。

此时如果执行如下语句:select * from A where id>16 for update. InnoDB会对(16,正无穷) 加锁,但在 read committed的事务隔离级别下,因为采用Record Lock,只会锁定20这个值.

如果在此时另外一个事务T2,插入了22这个值,此时, read committed 隔离级别下就会产生"幻读"的问题.

但在InnoDB默认存储引擎下的Next-key Lock 模式下,22是插入是会被阻塞的,直到事务T1提交后,释放X锁,才能提交22这值.这样,InnoDB就这样解决了幻读的问题.

总结:

本文主要参考:https://blog.csdn.net/tangkund3218/article/details/47704527

https://blog.csdn.net/suifeng629/article/details/99412343

上一篇下一篇

猜你喜欢

热点阅读