2018-9-10

read uncommitted(未提交读)

    在read uncommitted级别,事务中的修改,即使没有提交,对其他事务也都是可见的,事务可以读取未提交的数据,这也被称为脏读,这个级别会导致很多的问题,从性能上说,read uncommitted不会比其他的级别好太多,但却缺乏其他级别的很多好处,除非真的非常有必要的理由,实际应用中一般很少用到。

read committed(提交读)

    大多数数据库系统的默认隔离级别都是read committed(但mysql不是的),read committed满足前面的隔离性的简单定义:一个事务开始时,只能“看见”已经提交的事务所做的修改,换句话说,一个事务从开始到提交之前,所做的任何修改对其他的事务是不可见的,这个级别有时候也叫作不可重复读,因为两次执行同样的查询,可能会得到不一样的结果

repeatable read(可重复读)

    repeatable read 解决了脏读的问题,该级别保证了同一个事务中多次读取同样记录的结果是一致的,但是理论上,可重复读隔离级别还是无法解决另外一个幻读的问题,所谓幻读,指的是当某个事物在读取该范围的记录时,会产生幻行,InnoDB和XtraDB存储引擎通过多版本的并发控制(MVCC)来解决幻读问题。

serializable(可串行化)

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

四种隔离级别

隔离级别

脏读可能性

不可重复读可能性

幻读可能性

加锁读可能性

Read uncommitted

Yes

Yes

Yes

No

Read committed

No

Yes

Yes

No

Repeatable read

No

No

Yes

No

Serializable

No

No

No

Yes

    

多版本并发控制(MVCC)

可以认为MVCC是行级锁的一个变种,但是他在很多情况下避免了加锁操作,因此开销更低,虽然实现机制有所不同,但都实现了非阻塞的读操作,写操作也只锁定必要的行。

MVCC的实现,是通过保存数据在某个时间点的快照来实现的,也就是说,不管需要执行多长时间,每个事务看到的数据是一致的。更具事务的开始时间不同,每个事物对同一张表,同一时刻看到的数据就可能不一样。

MVCC典型的实现有乐观并发控制悲观并发控制,下面通过InnoDB的简化版行为来说明MVCC是如何工作的。

InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,

一个·保存了行的创建时间

一个保存了行的过期时间(或删除时间)

存储的并不是实际时间,而是系统版本号,没开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的版本号,用来和查询到每行记录的版本号进行比较,下面看一下repeatable read隔离级别下,MVCC是如何操作的

select 

     InnoDB会根据以下两个条件检查每行记录:

        a.InnoDB只查找版本早于当前事务的数据行,这样可以确保事务读取的行,要么是在事务开始抢就已经存在,要么就是事务自身插入或者修改过的

        b.行的删除版本要么未定义,要么大于当前事务的版本号,这可以确保事务读取到的行,在事务开始前被删除

只有符合上述两个条件的,才能返回作为查询结果

insert

    InnoDB为新插入的每一行保存当前系统版本号作为行版本号

delete

    InnoDB为删除的每一行保存当前系统版本号作为行删除表示

update

    InnoDB未插入一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识

MVCC只有在repeatable read 和Read committed两个隔离级别下工作,其他两个隔离级别都和MVCC不兼容,因为Read uncommitted总是读取最新的数行,而不是符合当前版本的数据行,而serializable则会对所有读取的行都加锁

猜你喜欢

转载自blog.csdn.net/robot_sh/article/details/82620390