Mysql的隔离级别及MVCC

一、Mysql的四个隔离级别

1.读未提交

B用户并未提交事务,但是A用户却能读到未提交的数据,这就是脏读

2.读已提交

解决脏读,同一个事务中,读取到两次不同的结果。这就造成了不可重复读,就是两次读取的结果不同。

3.可重复度

本来有id为1和2的数据,b查询发现有两条数据,a插入id=3数据,a查询有三条数据,
b查询有两条数据,插入id=3,报错
说是主键重复了,这时候B用户刚刚查询并没有id=3的记录。这就是幻读现象。
我的理解是:不可重复读指的是update操作,而幻读指的是insert或delete操作。

4.串行化
SERIALIZABLE是最高的隔离级别。它通过强制事务串行执行,避免了前面说的幻读的问题。简单来说,SERIALIZABLE会在读取每一行数据都加锁,所以可能导致大量的超时和锁争用问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。

二、MVCC(多版本并发控制)

锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销.

InnoDB的MVCC,是通过在每行纪录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存了行的过期时间(或删除时间),当然存储的并不是实际的时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行纪录的版本号进行比较.

select:满足以下两个条件innodb会返回该行数据:
(1)该行的创建版本号小于等于当前版本号,用于保证在select操作之前所有的操作已经执行落地。
(2)该行的删除版本号大于当前版本或者为空。删除版本号大于当前版本意味着有一个并发事务将该行删除了。

insert:将新插入的行的创建版本号设置为当前系统的版本号。

扫描二维码关注公众号,回复: 10281600 查看本文章

delete:将要删除的行的删除版本号设置为当前系统的版本号。

update:不执行原地update,而是转换成insert + delete。将旧行的删除版本号设置为当前版本号,并将新行insert同时设置创建版本号为当前版本号。

其中,写操作(insert、delete和update)执行时,需要将系统版本号递增。

由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做purge。

通过MVCC很好的实现了事务的隔离性,可以达到repeated read级别,要实现serializable还必须加锁。

发布了114 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44026997/article/details/105098370